惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MyScale Blog
MyScale Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
Y
Y Combinator Blog
月光博客
月光博客
IT之家
IT之家
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
L
LangChain Blog
博客园_首页
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
博客园 - Franky
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
V
Visual Studio Blog
小众软件
小众软件
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
KV locks for Workers cron jobs will silently fail — here'...
강해수 · 2026-06-24 · via DEV Community

강해수

A ghost lock blocked every cron trigger for 6 hours after a Korean ad-network API took 45 seconds to respond — 15 seconds past the Workers wall clock limit.

The Workers runtime doesn't queue a second invocation and wait for the first to finish. It fires the next cron tick regardless. So when my D1 write job occasionally crept past 30 seconds, two instances ran simultaneously, both inserting aggregated impression rows faster than my UNIQUE constraint could reject them. The 3am wake-up call was D1_ERROR: UNIQUE constraint failed: impressions.event_id.

The obvious fix is a distributed lock with a TTL — so even if the Worker dies mid-run without releasing, the lock eventually clears itself. I tried KV first because it's simpler. The code looks correct:

const existing = await env.KV.get(lockKey);
if (existing) return; // skip this tick
await env.KV.put(lockKey, "1", { expirationTtl: 55 });

It works — until it doesn't. KV is eventually consistent across Cloudflare PoPs. During a spike to ~12K writes/minute on an ad-server stress test, Cloudflare routed two consecutive triggers to different PoPs in the same minute. Both read null, both wrote the lock, both ran the full aggregation. Duplicate rows, again. KV locks are survivable if your job is idempotent. Mine wasn't, and I'd bet most non-trivial jobs aren't either.

The fix that actually held was a Durable Object acting as the lock. A single DO instance is strongly consistent — there's no eventual propagation window to race against. The DO stores a locked_until timestamp, and acquire returns HTTP 423 if that timestamp is still in the future. TTL is set to 55 seconds: just above the 30s wall clock, so a genuine overrun also self-clears within a minute without blocking the rest of the day's triggers.

The part that tripped me up in practice wasn't the lock logic — it was the [[migrations]] block in wrangler.toml. Skip it and you get a runtime binding error that's easy to misread as a code bug. I've hit it twice copy-pasting configs between projects.

I wrote up the full breakdown — including the complete DO class, the wrangler.toml wiring, and the specific failure scenario where even the DO approach has an edge case — over on dailymanuallab.com.

Full post →