1:"$Sreact.fragment"
2:I[75473,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
3:I[78515,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
4:I[30687,["/_next/static/chunks/fd0661f1506dcbc6.js"],"Toaster"]
5:I[61076,["/_next/static/chunks/fd0661f1506dcbc6.js"],"Analytics"]
7:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"OutletBoundary"]
8:"$Sreact.suspense"
a:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"ViewportBoundary"]
c:I[47913,["/_next/static/chunks/316a3a63422f35de.js"],"MetadataBoundary"]
e:I[90849,["/_next/static/chunks/316a3a63422f35de.js"],"default"]
:HL["/_next/static/chunks/609ea7bc18d0d15f.css","style"]
:HL["/_next/static/chunks/93b606aa9fdccd13.css","style"]
:HL["/_next/static/media/797e433ab948586e-s.p.479bea2b.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
:HL["/_next/static/media/caa3a2e1cccd8315-s.p.3b6cae6d.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
0:{"P":null,"b":"TlpKRvbES4zzM7LeczAM7","c":["","blog","idempotency-scheduled-jobs"],"q":"","i":false,"f":[[["",{"children":["blog",{"children":[["slug","idempotency-scheduled-jobs","d"],{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/609ea7bc18d0d15f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/chunks/93b606aa9fdccd13.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/_next/static/chunks/fd0661f1506dcbc6.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":[["$","head",null,{"children":[["$","script",null,{"async":true,"src":"https://www.googletagmanager.com/gtag/js?id=AW-18009878040"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"\n          window.dataLayer = window.dataLayer || [];\n          function gtag(){dataLayer.push(arguments);}\n          gtag('js', new Date());\n          gtag('config', 'AW-18009878040');\n          gtag('config', 'G-W3XKYXV2SG');\n\n          // Persist UTM and gclid params to sessionStorage for cross-page tracking\n          (function() {\n            var params = new URLSearchParams(window.location.search);\n            var keys = ['utm_source','utm_medium','utm_campaign','utm_content','utm_term','gclid'];\n            keys.forEach(function(k) {\n              var v = params.get(k);\n              if (v) sessionStorage.setItem(k, v);\n            });\n          })();\n        "}}]]}],["$","body",null,{"className":"font-sans antialiased","children":[["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}],["$","$L4",null,{"position":"top-center","richColors":true,"toastOptions":{"style":{"background":"var(--popover)","color":"var(--popover-foreground)","border":"1px solid var(--border)"}}}],["$","$L5",null,{}]]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":["$L6",[["$","script","script-0",{"src":"/_next/static/chunks/94245cbda44972fe.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/_next/static/chunks/af778fff4a0f4be6.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/_next/static/chunks/b096b037d08e2f31.js","async":true,"nonce":"$undefined"}]],["$","$L7",null,{"children":["$","$8",null,{"name":"Next.MetadataOutlet","children":"$@9"}]}]]}],{},null,false,false]},null,false,false]},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$La",null,{"children":"$Lb"}],["$","div",null,{"hidden":true,"children":["$","$Lc",null,{"children":["$","$8",null,{"name":"Next.Metadata","children":"$Ld"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$e",[]],"S":true}
f:I[15579,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Navigation"]
10:I[3013,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],""]
:HL["/blog/posts/idempotency-scheduled-jobs/hero.jpg","image"]
:HL["/blog/posts/logo.png","image"]
6:[["$","$Lf",null,{}],["$","main",null,{"className":"pt-20 md:pt-24","children":["$","article",null,{"children":[["$","header",null,{"className":"border-b border-border","children":["$","div",null,{"className":"container mx-auto px-6 py-14 md:py-20","children":[["$","$L10",null,{"href":"/blog","className":"mb-8 inline-flex items-center text-sm font-medium text-muted-foreground transition-colors hover:text-foreground","children":[["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-left mr-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1l729n",{"d":"m12 19-7-7 7-7"}],["$","path","x3x0zl",{"d":"M19 12H5"}],"$undefined"]}],"Blog"]}],["$","div",null,{"className":"grid gap-8 md:grid-cols-[1fr_0.9fr] md:items-start","children":[["$","div",null,{"className":"max-w-3xl","children":[["$","div",null,{"className":"mb-5 flex flex-wrap items-center gap-3 text-sm text-muted-foreground","children":[["$","span",null,{"className":"rounded-md border border-primary/40 bg-primary/10 px-2.5 py-1 text-primary","children":"Backend"}],["$","span",null,{"children":"2026-W20"}],["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":"4 min read"}],[["$","span",null,{"aria-hidden":"true","children":"/"}],["$","span",null,{"children":["by ",["$","span",null,{"className":"font-medium text-foreground","children":"Shard"}]]}]]]}],["$","h1",null,{"className":"text-4xl font-bold leading-tight text-balance md:text-6xl","children":"Idempotency in Scheduled Jobs — The Restart Problem"}],["$","p",null,{"className":"mt-6 text-lg leading-relaxed text-muted-foreground md:text-xl","children":"Scheduled jobs look sequential — one timer, one window, one run. They aren't. Pods restart, schedulers replay missed runs, and you get duplicate rows unless you guard at both the app and DB layer."}]]}],["$","div",null,{"className":"overflow-hidden rounded-lg border border-border bg-card","children":["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden","children":[null,["$","img",null,{"src":"/blog/posts/idempotency-scheduled-jobs/hero.jpg","alt":"An industrial timestamp clock on a worn wooden desk with two identical printed slips showing the same stamped time stacked beside it, soft window light, no people.","className":"h-full w-full object-cover"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-4 top-4 h-[50px] w-[50px] mix-blend-screen"}]]}]}]]}]]}]}],["$","div",null,{"className":"container mx-auto px-6 py-12 md:py-16","children":["$","div",null,{"className":"grid gap-10 lg:grid-cols-[minmax(0,1fr)_280px] lg:items-start","children":[["$","div",null,{"className":"max-w-3xl text-muted-foreground","children":[[["$","h2","h2-0",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The problem"}],"\n",["$","p","p-0",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"You have an hourly job that computes a Merkle digest over the past hour's events and stores the result. The scheduler fires at :05. It runs, inserts a row, delivers to webhooks, commits. Done."}],"\n",["$","p","p-1",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["Then the process restarts at :06. APScheduler fires the missed job on startup. The job runs again for the same window. Now you have two digest rows for the same ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"(org_id, window_start)"}],". Customers querying the digest endpoint see duplicate roots. Your tamper-evidence proof is ambiguous about which one is authoritative."]}],"\n","$L11","\n","$L12","\n","$L13","\n","$L14","\n","$L15","\n","$L16","\n","$L17","\n","$L18","\n","$L19","\n","$L1a","\n","$L1b"],"$L1c",null]}],"$L1d"]}]}]]}]}],"$L1e"]
2c:I[41451,["/_next/static/chunks/fd0661f1506dcbc6.js","/_next/static/chunks/94245cbda44972fe.js","/_next/static/chunks/af778fff4a0f4be6.js","/_next/static/chunks/b096b037d08e2f31.js"],"Footer"]
11:["$","p","p-2",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"This isn't rare. Scheduled jobs restart. Kubernetes pods get evicted. Processes crash after the insert but before the commit. The second run needs to be safe."}]
12:["$","h2","h2-1",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"The approach"}]
13:["$","p","p-3",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Two layers. First, an application-level guard:"}]
14:["$","div","pre-0",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"className":"$undefined","style":{},"children":["existing "]}],["$","span","code-segment-1",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["="]}],["$","span","code-segment-2",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-3",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["await"]}],["$","span","code-segment-4",{"className":"$undefined","style":{},"children":[" db"]}],["$","span","code-segment-5",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-6",{"className":"$undefined","style":{},"children":["execute"]}],["$","span","code-segment-7",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-8",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-9",{"className":"$undefined","style":{},"children":["    select"]}],["$","span","code-segment-10",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-11",{"className":"$undefined","style":{},"children":["OrgMerkleDigest"]}],["$","span","code-segment-12",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-13",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-14",{"className":"$undefined","style":{},"children":["where"]}],["$","span","code-segment-15",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-16",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-17",{"className":"$undefined","style":{},"children":["        and_"]}],["$","span","code-segment-18",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-19",{"className":"$undefined","style":{},"children":["OrgMerkleDigest"]}],["$","span","code-segment-20",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-21",{"className":"$undefined","style":{},"children":["organization_id "]}],["$","span","code-segment-22",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["=="]}],["$","span","code-segment-23",{"className":"$undefined","style":{},"children":[" org_id"]}],["$","span","code-segment-24",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[","]}],["$","span","code-segment-25",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-26",{"className":"$undefined","style":{},"children":["             OrgMerkleDigest"]}],["$","span","code-segment-27",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-28",{"className":"$undefined","style":{},"children":["window_start "]}],["$","span","code-segment-29",{"className":"token","style":{"color":"hsl(207, 82%, 66%)"},"children":["=="]}],["$","span","code-segment-30",{"className":"$undefined","style":{},"children":[" window_start"]}],["$","span","code-segment-31",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-32",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-33",{"className":"$undefined","style":{},"children":["    "]}],["$","span","code-segment-34",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-35",{"className":"$undefined","style":{},"children":["\n"]}],["$","span","code-segment-36",{"className":"$undefined","style":{},"children":[""]}],["$","span","code-segment-37",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}],["$","span","code-segment-38",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["."]}],["$","span","code-segment-39",{"className":"$undefined","style":{},"children":["scalar_one_or_none"]}],"$L1f","$L20","$L21","$L22","$L23","$L24","$L25","$L26","$L27","$L28","$L29","$L2a"]]}]}]
15:["$","p","p-4",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Second, a database-level constraint:"}]
16:["$","div","pre-1",{"style":{"background":"hsl(220, 13%, 18%)","color":"hsl(220, 14%, 71%)","textShadow":"0 1px rgba(0, 0, 0, 0.3)","fontFamily":"\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace","direction":"ltr","textAlign":"left","whiteSpace":"pre","wordSpacing":"normal","wordBreak":"normal","lineHeight":"1.5","MozTabSize":"2","OTabSize":"2","tabSize":"2","WebkitHyphens":"none","MozHyphens":"none","msHyphens":"none","hyphens":"none","padding":"1rem","margin":"0.5em 0","overflow":"auto","borderRadius":"0.5rem","marginTop":"1.25rem","marginBottom":0,"border":"1px solid hsl(var(--border))","fontSize":"0.875rem"},"children":["$","code",null,{"style":{"whiteSpace":"pre","fontFamily":"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"},"children":[false,[["$","span","code-segment-0",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["UNIQUE"]}],["$","span","code-segment-1",{"className":"$undefined","style":{},"children":[" "]}],["$","span","code-segment-2",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}],["$","span","code-segment-3",{"className":"$undefined","style":{},"children":["organization_id"]}],["$","span","code-segment-4",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[","]}],["$","span","code-segment-5",{"className":"$undefined","style":{},"children":[" window_start"]}],["$","span","code-segment-6",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}]]]}]}]
17:["$","p","p-5",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"The application guard handles the common case fast and without a DB error. The unique constraint handles races — if two instances of the job run concurrently (split-brain scenario, or a bug in the guard), exactly one insert succeeds and the other gets a constraint violation, which the caller can treat as \"already done.\""}]
18:["$","p","p-6",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Both layers are needed. The application guard alone fails under concurrent execution. The constraint alone turns normal restart behavior into an error you have to swallow. Together they make the job correct by default."}]
19:["$","h2","h2-2",{"className":"mt-12 text-2xl font-semibold leading-snug text-foreground first:mt-0","children":"What I learned"}]
1a:["$","p","p-7",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":"Scheduled jobs are the easiest place to forget idempotency because they look sequential. One job, one timer, one run per window. But \"sequential in the happy path\" isn't \"safe under restarts.\" The question to ask before shipping any scheduled job: \"if this job runs twice for the same inputs, is the second run a no-op or a corruption?\""}]
1b:["$","p","p-8",{"className":"mt-4 text-base leading-8 md:text-lg first:mt-0 first:text-xl first:leading-relaxed first:text-foreground md:first:text-2xl","children":["If the answer is \"corruption\" — duplicated rows, doubled charges, duplicate deliveries — add the guard before you ship. It's three lines of SQL and a ",["$","code","code-0",{"className":"rounded bg-secondary px-1.5 py-0.5 text-[0.9em] text-foreground","children":"return"}],". The cost of adding it after a production incident is much higher."]}]
1c:["$","div",null,{"className":"mt-14 border-t border-border pt-8","children":["$","$L10",null,{"href":"/platform","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Start a build",["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]]}]}]
1d:["$","aside",null,{"className":"hidden lg:block","children":["$","div",null,{"className":"sticky top-24 space-y-4","children":[["$","h3",null,{"className":"text-xs font-semibold uppercase tracking-wider text-primary","children":["More in ","Backend"]}],["$","div",null,{"className":"space-y-4","children":[["$","$L10","pydantic-production-fail-fast",{"href":"/blog/pydantic-production-fail-fast","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/pydantic-production-fail-fast/hero.jpg","alt":"A solid brass padlock with its key still inserted, resting on a worn leather-bound logbook with handwritten entries, soft warm desk light, no people, editorial.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W20"," · ","5 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Fail Fast at the Right Boundary — Pydantic Settings in Production"}]]}]]}],["$","$L10","postgres-notify-ws-delivery",{"href":"/blog/postgres-notify-ws-delivery","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/postgres-notify-ws-delivery/hero.jpg","alt":"Close shot of a server rack with a single blinking amber LED in an otherwise dark row.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W18"," · ","3 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"Postgres NOTIFY as a WebSocket Delivery Mechanism"}]]}]]}],["$","$L10","stream-wrapper-pattern",{"href":"/blog/stream-wrapper-pattern","className":"block overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40","children":[["$","div",null,{"className":"relative aspect-[16/9] overflow-hidden bg-secondary/70","children":[["$","img",null,{"src":"/blog/posts/stream-wrapper-pattern/hero.jpg","alt":"A clear glass laboratory pipette suspended over a beaker with a single amber drop forming at its tip.","className":"h-full w-full object-cover","loading":"lazy","decoding":"async"}],["$","img",null,{"src":"/blog/posts/logo.png","alt":"","aria-hidden":"true","className":"pointer-events-none absolute right-2 top-2 h-[24px] w-[24px] mix-blend-screen"}]]}],["$","div",null,{"className":"p-4","children":[["$","p",null,{"className":"text-xs font-medium text-primary","children":"Backend"}],["$","p",null,{"className":"mt-1 text-xs text-muted-foreground","children":["2026-W18"," · ","3 min"]}],["$","p",null,{"className":"mt-2 line-clamp-2 text-sm font-semibold leading-snug text-foreground","children":"The Stream Wrapper Pattern for Transparent Event Capture"}]]}]]}]]}],["$","$L10",null,{"href":"/blog?category=backend","className":"inline-flex items-center text-sm font-medium text-primary transition-colors hover:text-primary/80","children":["Read all in ","Backend","$L2b"]}]]}]}]
1e:["$","$L2c",null,{}]
1f:["$","span","code-segment-40",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":["("]}]
20:["$","span","code-segment-41",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[")"]}]
21:["$","span","code-segment-42",{"className":"$undefined","style":{},"children":["\n"]}]
22:["$","span","code-segment-43",{"className":"$undefined","style":{},"children":[""]}]
23:["$","span","code-segment-44",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["if"]}]
24:["$","span","code-segment-45",{"className":"$undefined","style":{},"children":[" existing"]}]
25:["$","span","code-segment-46",{"className":"token","style":{"color":"hsl(220, 14%, 71%)"},"children":[":"]}]
26:["$","span","code-segment-47",{"className":"$undefined","style":{},"children":["\n"]}]
27:["$","span","code-segment-48",{"className":"$undefined","style":{},"children":["    "]}]
28:["$","span","code-segment-49",{"className":"token","style":{"color":"hsl(286, 60%, 67%)"},"children":["return"]}]
29:["$","span","code-segment-50",{"className":"$undefined","style":{},"children":["  "]}]
2a:["$","span","code-segment-51",{"className":"token","style":{"color":"hsl(220, 10%, 40%)","fontStyle":"italic"},"children":["# already processed this window"]}]
2b:["$","svg",null,{"ref":"$undefined","xmlns":"http://www.w3.org/2000/svg","width":24,"height":24,"viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":2,"strokeLinecap":"round","strokeLinejoin":"round","className":"lucide lucide-arrow-right ml-2 h-4 w-4","aria-hidden":"true","children":[["$","path","1ays0h",{"d":"M5 12h14"}],["$","path","xquz4c",{"d":"m12 5 7 7-7 7"}],"$undefined"]}]
b:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
2d:I[94060,["/_next/static/chunks/316a3a63422f35de.js"],"IconMark"]
9:null
d:[["$","title","0",{"children":"Idempotency in Scheduled Jobs — The Restart Problem — Bridgestack"}],["$","meta","1",{"name":"description","content":"Scheduled jobs look sequential — one timer, one window, one run. They aren't. Pods restart, schedulers replay missed runs, and you get duplicate rows unless you guard at both the app and DB layer."}],["$","meta","2",{"name":"generator","content":"v0.app"}],["$","meta","3",{"property":"og:title","content":"Bridgestack — custom software, flat prices from $9.99"}],["$","meta","4",{"property":"og:description","content":"Talk to Tom, your AI PM. A fleet of AI agents builds your product. Flat one-time price. 7 days to test before you pay. Source code is yours."}],["$","meta","5",{"property":"og:url","content":"https://www.bridgestack.systems"}],["$","meta","6",{"property":"og:site_name","content":"Bridgestack"}],["$","meta","7",{"property":"og:locale","content":"en_US"}],["$","meta","8",{"property":"og:image","content":"https://www.bridgestack.systems/bridgestack-landscape-1200x628.png"}],["$","meta","9",{"property":"og:image:width","content":"1200"}],["$","meta","10",{"property":"og:image:height","content":"628"}],["$","meta","11",{"property":"og:type","content":"website"}],["$","meta","12",{"name":"twitter:card","content":"summary_large_image"}],["$","meta","13",{"name":"twitter:title","content":"Bridgestack — custom software, flat prices from $9.99"}],["$","meta","14",{"name":"twitter:description","content":"Talk to Tom, your AI PM. A fleet of AI agents builds your product. 7 days to test before you pay. Source code is yours."}],["$","meta","15",{"name":"twitter:image","content":"https://www.bridgestack.systems/bridgestack-landscape-1200x628.png"}],["$","link","16",{"rel":"icon","href":"/icon-light-32x32.png","media":"(prefers-color-scheme: light)"}],["$","link","17",{"rel":"icon","href":"/icon-dark-32x32.png","media":"(prefers-color-scheme: dark)"}],["$","link","18",{"rel":"icon","href":"/icon.svg","type":"image/svg+xml"}],["$","link","19",{"rel":"apple-touch-icon","href":"/apple-icon.png"}],["$","$L2d","20",{}]]
