{"id":46481393,"url":"https://github.com/block65/server-timing","last_synced_at":"2026-03-06T08:16:20.330Z","repository":{"id":65525296,"uuid":"507999337","full_name":"block65/server-timing","owner":"block65","description":"Track and log timing metrics during async request-response cycles and surface them as a Server-Timing header","archived":false,"fork":false,"pushed_at":"2022-09-24T08:14:46.000Z","size":309,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-12-27T05:23:56.675Z","etag":null,"topics":["async-await","nodejs","server-timing"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@block65/server-timing","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/block65.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-27T17:19:38.000Z","updated_at":"2022-09-24T08:12:39.000Z","dependencies_parsed_at":"2023-01-27T08:05:17.213Z","dependency_job_id":null,"html_url":"https://github.com/block65/server-timing","commit_stats":null,"previous_names":[],"tags_count":5,"template":null,"template_full_name":null,"purl":"pkg:github/block65/server-timing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block65%2Fserver-timing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block65%2Fserver-timing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block65%2Fserver-timing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block65%2Fserver-timing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/block65","download_url":"https://codeload.github.com/block65/server-timing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block65%2Fserver-timing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30167205,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async-await","nodejs","server-timing"],"created_at":"2026-03-06T08:16:19.775Z","updated_at":"2026-03-06T08:16:20.306Z","avatar_url":"https://github.com/block65.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @block65/server-timing\n\nFrom https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing\n\n\u003e The Server-Timing header communicates one or more metrics and descriptions for a given request-response cycle. It is used to surface any backend server timing metrics (e.g. database read/write, CPU time, file system access, etc.) in the developer tools in the user's browser or in the PerformanceServerTiming interface.\n\nThis library helps you track and log timing metrics during the request response cycles of your app\n\n## Usage\n\n## As Express middleware\n\nThis middleware automatically appends a `Server-Timing` header with a `total` metric alongside your own metrics\n\n```typescript\n/// \u003creference lib=\"dom\" /\u003e\nimport express from 'express';\nimport { createServerTimingContext } from '@block65/server-timing';\nimport { createServerTimingExpressMiddleware } from '@block65/server-timing/express';\n\nasync function doSomeAsyncStuff() {\n  const measure = timing.try((t) =\u003e t.mark('asyncstuff'));\n\n  return new Promise((resolve) =\u003e {\n    setTimeout(() =\u003e resolve('some random value'), 1000);\n  }).then(measure);\n}\n\n// Create a timing context\nconst timing = createServerTimingContext();\nconst middleware = createServerTimingExpressMiddleware(timing);\n\n// express v5 example with async route handler\nconst server = express()\n  .use(middleware)\n  .get('/', async (_, res) =\u003e {\n    const someRandomValue = await doSomeAsyncStuff();\n    res.send(someRandomValue);\n  })\n  .listen(3000);\n\nconsole.log(\n  await fetch('http://localhost:3000').then((res) =\u003e\n    res.headers.get('Server-Timing'),\n  ),\n);\n// -\u003e asyncstuff;dur=1002.11, total;dur=1003.44\n\nserver.close();\n```\n\n### General Async\n\nA convoluted example of how to run async functions and record timing metrics\n\n```typescript\nimport { createServerTimingContext } from '@block65/server-timing';\n\n// first create a context for server timing\nconst timing = createServerTimingContext();\n\nasync function doSomeAsyncStuff() {\n  const measure = timing.try((t) =\u003e t.mark('asyncstuff'));\n\n  return new Promise((resolve) =\u003e {\n    setTimeout(() =\u003e resolve('some random value'), 1000);\n  }).then(measure);\n}\n\n// server timing is usually used in a request-response cycle\n// this is just a demo\nawait timing.run(async () =\u003e {\n  await doSomeAsyncStuff();\n  console.log(timing.try((t) =\u003e t.toString()));\n  // -\u003e asyncstuff:dur=1002.39\n});\n```\n\n### `ServerTiming` class\n\nAn instance of the `ServerTiming` class is the first argument to `timing.try` and can be used standalone if desired\n\n```typescript\nimport { ServerTiming } from '@block65/server-timing';\n\nconst t = new ServerTiming();\n\n// increment the timing mark called `test`\nt.inc('test', 10);\n\n// chain increments for multiple marks\nt.inc('test', 100).inc('test2', 100);\n\n// decrement using negative values\nt.inc('test', -33);\n\n// set a description for the timing mark `test`\nt.meta('test', {\n  desc: 'Just a test metric',\n});\n\nconst measure = t.mark('promise');\n\nawait new Promise((resolve) =\u003e {\n  setTimeout(resolve, 1000);\n}).then(measure);\n\nconsole.log(t.toString());\n\n// -\u003e test:dur=77,desc=\"Just a test metric\"; test2:dur=100; promise:dur=1001.71\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock65%2Fserver-timing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblock65%2Fserver-timing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock65%2Fserver-timing/lists"}