SOFTWARE AND DATA ENGINEERING

One fee row made 32 clients exactly as fast as one, and the checkpoint that replaced it lost 2,215 entries in 30 seconds without raising⊠Continue reading on Dev Genius »
TIHOMIRLEILANI
ARTIFICIAL INTELLIGENCE

A test in a payments service goes red. FeeCalculatorTest expects a convenience fee of 20.00 Continue reading on Dev Genius »
FEE CALCULATOR TESTDEVELOPER
COMPUTING INFRASTRUCTURE AND HARDWARE
Building a Production Transit Monitor on the Edge
#### The $0.00/Month Architecture At 06:56 on a Tuesday, 312 commuters stood on a freezing platform in Puchheim waiting for a train that had been silently terminated 15 kilometers east ten minutes prior. The Munich commuter rail network moves hundreds of thousands of people daily. Every single suburban line funnels into a single twin-track tunnel cutting under the city center. The Stammstrecke. A signal failure in the eastern suburbs creates a cascading collapse across the entire network. The central tunnel chokes. Dispatchers intervene with a Vorzeitige Wende. A heavily delayed westbound train terminates early at Pasing station. It turns back east to clear the bottleneck. Passengers waiting at suburban stops like LeienfelsstraĂe watch the platform displays. The train simply vanishes from the board without warning. Standard transit notification systems fail to handle this gracefully. A naive polling bot observes delay fluctuations. The feed reports an eleven-minute delay. One minute later, it reports twelve minutes. The next minute, it reports eleven again. The bot spams the team channel with dozens of redundant notifications. The human operators mute the channel. They miss the actual cancellation event when it occurs. The architectural solution requires a specific approach. It demands a zero-cost, serverless runtime operating at the global edge. It needs a state machine that dampens noise. It requires a dead-man switch to survive silent cloud scheduler failures. This advisory breaks down the exact architectural decisions required to build a high-signal, zero-spam alerting system for transit infrastructure. The typical lifecycle in a state machine. #### The Architectural Decision Matrix Building a resilient monitoring system forces a series of structural choices. The naive path looks simple. The hardened path requires diligence. #### Decision 1 The Zero-Ingress Perimeter Accepting incoming traffic creates an attack surface. A traditional webhook endpoint requires a listening HTTP port. That port attracts scans, probes, and denial of service attempts. Securing that endpoint demands authentication logic, rate limiting, and constant patching. The Transit Monitor avoids this entirely. It runs as a purely time-dispatched compute workload. A scheduled timer triggers the V8 isolate every minute. The isolate executes its logic and terminates. No public endpoints exist. No webhooks accept incoming traffic. Dropping the workers_dev flag in the configuration file strips the default subdomain from the deployment. This action removes the only default route an attacker could probe. The platform drops unauthenticated traffic at the edge firewall. Any external attempt to reach the application returns a 404 response.
name = "transit-monitor" main = "src/index.js" compatibility_date = "2024-09-23" workers_dev = false [triggers] crons = ["* * * * *"] [[kv_namespaces]] binding = "STATE_STORE" id = "your-kv-namespace-id" Validating the perimeter requires an external request. An attacker probing the deployment receives an immediate rejection. curl -v https://transit-monitor.your-subdomain.workers.dev # Expected output: # < HTTP/1.1 404 Not Found # < Server: cloudflare #### Decision 2 The Operational Time Gate A systematic overview. (Kudos to Archify by the way.) Cloud schedulers bill for execution time. Running complex logic 1,440 times a day quickly burns through free-tier quotas. The monitoring system only matters during the morning commute. The worker wakes up every minute. It performs a high-speed, zero-cost timezone gate check using the IANA timezone database. The V8 isolate executes this logic in less than a single millisecond. If the invocation occurs on a weekend or outside the commute window, the worker exits immediately. This ensures the 1,440 daily cron executions consume virtually zero billable CPU time outside the active morning window. function isWithinCommuteWindow(currentDate) { const formatter = new Intl.DateTimeFormat('en-US', { timeZone: 'Europe/Berlin', weekday: 'short', hour: '2-digit', minute: '2-digit', hour12: false }); const parts = formatter.formatToParts(currentDate); const weekday = parts.find(p => p.type === 'weekday').value; const hour = parseInt(parts.find(p => p.type === 'hour').value, 10); const minute = parseInt(parts.find(p => p.type === 'minute').value, 10); const isWeekday = !['Sat', 'Sun'].includes(weekday); const currentTime = hour * 60 + minute; const windowStart = 6 * 60 + 30; // 06:30 const windowEnd = 7 * 60 + 50; // 07:50 return isWeekday && currentTime >= windowStart && currentTime <= windowEnd; } Skipping this gate means the worker ingests transit feeds and queries databases 1,440 times a day. The free tier evaporates. The cron trigger becomes a liability. #### Decision 3 The In-Process Edge Fabric Tracking a moving train requires memory. The system must know the alerted delay state from the previous minute. A traditional microservice connects to a managed PostgreSQL instance. Serverless V8 isolates struggle with persistent TCP connections to databases. Connection pooling adds latency and consumes CPU. Opening a database connection on a cold start introduces a 300-millisecond delay. The platform provides an in-memory key-value store. The communication occurs over in-process V8 bindings. Zero network hops. Sub-millisecond latency. The store maintains the state of each active commuter slot. It automatically purges old records via a 36-hour time-to-live expiration policy. { "slotId": "0656", "trainNumber": "6420", "currentState": "DELAYED", "alertedDelayMin": 12, "lastUpdated": "2024-09-23T05:56:00Z", "cidHistory": ["atp-post-123", "atp-post-124"] } The state machine persists this structure back to the state store with a 36-hour TTL. Silent minutes that show no change or minor fluctuations under threshold bypass write operations entirely. This conserves the write quota. async function persistSlotState(env, slotId, stateData) { const key = `slot:${slotId}`; const ttl = 60 * 60 * 36; // 36 hours await env.STATE_STORE.put(key, JSON.stringify(stateData), { expirationTtl: ttl }); } Failing to set the expirationTtl parameter leaves orphan database records. The storage fills with historical train states. Manual cleanup jobs become necessary. The zero-maintenance storage guarantee disappears. #### Decision 4 The Transit Data Horizon The monitor initiates outbound-only, TLS 1.3-encrypted connections to three distinct public transit data sources. Each source serves a specific tier in the resilience ladder. The geOps WebSocket API provides real-time train radar data. The connection subscribes to departures for the origin station. It provides exact physical train numbers, GPS-derived arrival timestamps, and operational flags. async function ingestLiveTransitStream(originStationId) { const socket = new WebSocket('wss://api.geops.io:443'); const departures = []; let silenceTimer; const connectionPromise = new Promise((resolve, reject) => { socket.onopen = () => { socket.send(`GET timetable_${originStationId}`); silenceTimer = setTimeout(() => { socket.close(); resolve(departures); }, 400); // 400 ms quiet-window accumulator }; socket.onmessage = (event) => { clearTimeout(silenceTimer); const data = JSON.parse(event.data); departures.push(...data); silenceTimer = setTimeout(() => { socket.close(); resolve(departures); }, 400); }; socket.onerror = (error) => reject(error); }); // 2.5-second hard safety ceiling return Promise.race([ connectionPromise, new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 2500) ) ]); } Railway WebSocket streams do not emit an end-of-file frame. They emit an immediate burst of 10 to 12 departure objects within 200 to 300 milliseconds. The worker implements an accumulator with a 400-millisecond silence timer. As soon as the feed goes quiet, the worker resolves the full departure array and cleanly closes the socket. Relying on a continuous stream connection kills the serverless isolate. The cron execution hits its CPU limit. The quiet-window accumulator cleanly resolves burst frames without relying on non-existent EOF signals. The S-Bahn Leitstelle on Bluesky provides human-written disruption notices. The worker fetches the latest 15 posts via HTTPS GET. It filters the posts against an expanded corridor vocabulary. curl -s "https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=sbahnmuenchen.bsky.social&limit=15" | jq '.feed[].post.record.text' The filter covers the critical upstream eastern feeder stations. A technical fault in Grafing Bahnhof strikes the western corridor 30 to 45 minutes later. Catching the eastern keyword provides an upstream early warning system. const CORRIDOR_KEYWORDS = [ '#S4', '#Stammstrecke', '#Pasing', '#Puchheim', '#Buchenau', '#Geltendorf', '#Grafing', '#Ebersberg', '#Zorneding', '#Trudering', '#Ostbahnhof', '#DonnersbergerbrĂŒcke' ]; function filterRelevantIncidents(posts) { return posts.filter(post => CORRIDOR_KEYWORDS.some(keyword => post.text.toLowerCase().includes(keyword.toLowerCase()) ) ); } Ignoring the upstream eastern filter removes the 30-minute early warning advantage. Passengers only learn about the delay when the train fails to arrive. The system becomes reactive rather than predictive. The MVV EFA Gateway provides the static scheduled timetable baseline. This acts as a secondary fallback if the live radar stream experiences transient upstream outages. #### Decision 5 The Hysteresis State Machine Alert fatigue destroys monitoring systems. A train fluctuating between +11 and +12 minutes generates continuous state transitions. A naive system alerts on every change. Humans mute the channel. The Transit Monitor implements an escalation hysteresis threshold. An initial alert fires when a train reaches a three-minute delay. The system records this value in the state store. It remains silent for minor fluctuations. It only fires another alert if the delay worsens by five or more additional minutes. function evaluateDelayTransition(currentDelay, storedState) { const INITIAL_THRESHOLD = 3; const ESCALATION_JUMP = 5; if (currentDelay < INITIAL_THRESHOLD) { return { shouldAlert: false, newState: 'ON_TIME' }; } if (!storedState || !storedState.alertedDelayMin) { return { shouldAlert: true, newState: 'DELAYED', alertDelay: currentDelay, message: `:rotating_light: S4 delayed +${currentDelay} min` }; } const escalationDelta = currentDelay - storedState.alertedDelayMin; if (escalationDelta >= ESCALATION_JUMP) { return { shouldAlert: true, newState: 'DELAYED', alertDelay: currentDelay, message: `:warning: delay INCREASED by +${escalationDelta} min (Now: +${currentDelay} min)` }; } return { shouldAlert: false, newState: 'DELAYED', alertDelay: storedState.alertedDelayMin }; } Bypassing this hysteresis logic causes the +12m to +13m to +12m loop. The channel fills with noise. The actual cancellation event scrolls past the visible screen area. The user misses the critical update. The system models each commuter train as a dynamic entity passing through four operational swimlanes. The slot lifecycle begins at 06:30 when all four commuter slots instantiate in the SCHEDULED state. The passenger expects a train. No live telemetry has been processed. As the geOps live stream ingests, the engine matches incoming westbound departures. Rather than binding to fragile DB train numbers, the engine correlates live trains to commuter slots based on planned departure time windows. The 06:36 slot accepts trains scheduled between 06:26 and 06:45. const COMMUTER_SLOTS = [ { slotId: '0636', windowStart: '06:26', windowEnd: '06:45', terminus: ['Buchenau', 'Geltendorf'] }, { slotId: '0656', windowStart: '06:46', windowEnd: '07:05', terminus: ['Geltendorf'] }, { slotId: '0716', windowStart: '07:06', windowEnd: '07:25', terminus: ['Geltendorf'] }, { slotId: '0736', windowStart: '07:26', windowEnd: '07:46', terminus: ['Buchenau', 'Geltendorf'] } ]; Binding to DB train numbers fails when dispatchers swap standard runs for booster runs. The time-window matching engine provides resilience against operational fleet substitutions. When trains are scheduled more than 40 minutes into the future, transit feeds report departureDelay: null. The GPS tracking has not locked onto the locomotive. The engine gracefully falls back to estimated versus planned timestamps. This prevents NaN calculation failures. function calculateDelayMinutes(departure) { if (departure.departureDelay === null || departure.departureDelay === undefined) { const planned = new Date(departure.plannedDeparture).getTime(); const estimated = new Date(departure.estimatedDeparture).getTime(); return Math.max(0, Math.round((estimated - planned) / 60000)); } return departure.departureDelay; } If dispatch reverses the train at Munich-Pasing, or if the trainâs state becomes CANCELLED or DELETED, the slot transitions immediately to Route Cancelled. function handleCancellation(departure, slotState) { if (departure.state === 'CANCELLED' || departure.state === 'DELETED' || departure.shortTurn) { return { shouldAlert: true, newState: 'CANCELLED', message: `:x: CANCELLED / SHORT TURN | Slot: *${slotState.slotId}* â will NOT call at LeienfelsstraĂe.` }; } return null; } Once the train physically calls at and departs LeienfelsstraĂe, the observation finalizes. No further delay calculations occur for that slot. #### Decision 6 The Dead-Man Switch Cloud infrastructure fails silently. Scheduled cron events stop firing. The cloud provider generates no error logs. The system simply dies. The team assumes the monitor works. They receive no alerts. They miss the cancellations. The worker transmits a secure heartbeat ping to an external dead-man monitor at the conclusion of every successful in-window run. If the heartbeat misses for more than a few minutes during the morning commute, the external service triggers an on-call alert independently. curl -X POST "https://hc-ping.com/your-uuid-here" -m 10 The implementation requires a rapid HTTPS POST request sent after the notification egress phase. async function sendDeadManHeartbeat(env) { try { await fetch(env.DEAD_MAN_URL, { method: 'POST', signal: AbortSignal.timeout(2000) }); } catch (error) { console.error('Heartbeat failed:', error); } } Omitting the AbortSignal.timeout parameter allows a hanging DNS resolution or TCP handshake to consume the entire worker execution budget. The isolate terminates. The heartbeat never reaches the external monitor. The on-call alert fails to trigger. #### Decision 7 The Daily Summary and Slot Locking At 07:46, the morning commute concludes. The worker evaluates the entire morning history from the state store. It compiles a clean, scannable executive summary card. async function postDailySummary(env, slots) { const summaryLockKey = 'summary_lock_' + new Date().toISOString().split('T')[0]; const lock = await env.STATE_STORE.get(summaryLockKey); if (lock) { return; // Summary already posted today } const summaryText = formatSummaryMessage(slots); await sendSlackNotification(env, summaryText); await env.STATE_STORE.put(summaryLockKey, 'posted', { expirationTtl: 60 * 60 * 24 // 24 hours }); } Forgetting the summary lock causes the system to post a duplicate summary card every minute between 07:46 and 07:50. The channel spams with identical recaps. The lock key must include the date string to ensure a fresh lock each morning. #### Validation and Operational Proof Depicting the sequence of things! The implementation succeeds when the external dead-man monitor shows continuous pings every minute between 06:30 and 07:50 on weekdays. The team channel receives exactly one summary card at 07:46. The Slack notification history shows an initial alert at +3 minutes, an escalation alert at +8 minutes, and a cancellation alert for the short-turned train. The state store contains exactly four active slot keys with 36-hour TTLs. The zero-ingress perimeter drops all external probe attempts with 404 responses. The system operates within the free-tier quota limits. More actionable advice over at https://mohammed-brueckner.com/publications â and discover the playbook for surviving the compression in the agentic era with my book at https://platformeconomies.com â out now and ready to buy in both Kindle and hardcover Direct Amazon links: - Amazon US: https://www.amazon.com/dp/B0H3VVNPZ3 - Amazon UK: https://www.amazon.co.uk/dp/B0H3VVNPZ3 - Amazon DE: https://www.amazon.de/dp/B0H3VVNPZ3 â mohammed-brueckner.com --- Building a Production Transit Monitor on the Edge was originally published in Dev Genius on Medium, where people are continuing the conversation by highlighting and responding to this story.PUCHHEIMPASINGGEOPSIANA
ARTIFICIAL INTELLIGENCE
Top Apps for Tracking Multiple Coding Agent Usage and Reset Times
I use more than one coding agent. Maybe you do too. Claude Code for some things. Codex for others. Cursor when I want a different workflow. And sometimes, more than one account. At first, it doesnât feel like a problem. Then one day youâre sitting in the middle of a coding session thinking: âWait⊠how much usage do I have left?â So you open Claude. Then Codex. Then Cursor. Then you try to remember which account youâre looking at. And suddenly, checking your AI usage has become a tiny job of its own. I started looking for something simpler. Not another AI coding tool. Not another analytics dashboard. Just a small app that could tell me: What do I have left? When does it reset? Which account should I use? Here are some of the apps I found. ### 1. Usage Buddy Usage Buddy is built around a very simple idea: > All your coding agents. One usage view. It brings Codex, Claude Code, and Cursor accounts into one desktop view. You can see usage, remaining allowance, reset times, account names, and connection status without opening each service separately. It also supports multiple accounts, automatic refresh, alerts, and local storage of credentials and usage data. The multiple-account part is probably the most useful. You can have: Personal Codex Work Codex Claude Code Cursor and see them together. No switching between browser tabs just to find out which account still has room. Usage Buddy is currently Windows-focused, which is worth knowing if youâre on macOS. And thatâs really the philosophy behind it. It doesnât try to tell you how you should code. It just tells you how much room you have left to code. ### 2. UsageAtlas UsageAtlas takes a slightly different approach. It brings Claude Code and Codex together in one local dashboard and can also include Cursor and OpenCode. Instead of only looking at current limits, it focuses more on the bigger picture: - Usage windows - Tokens - Estimated cost - History - Combined usage You can even look at Claude and Codex together instead of treating them as completely separate tools. I like this approach if you want to understand your usage over time. But if your only question is: > âCan I keep using this account right now?â then some of the analytics can feel like more information than you need. ### 3. AgentPeek If youâre on a Mac, AgentPeek is another interesting option. It lives on your Mac and focuses on AI coding usage from tools such as Claude Code, Codex, and Cursor. It shows things like: - 5-hour usage - 7-day usage - Monthly usage - Reset/refill times - History - Alerts It also supports a wider set of agents where usage information is available. The nice thing about this type of app is that it stays close to your workflow. You donât need to open a website. You donât need to remember another dashboard. You can simply glance at it. The downside is also pretty simple: itâs a Mac-focused experience. So it wonât help much if youâre sitting on Windows. ### 4. UsageMaster UsageMaster is another Mac menu-bar app built around the same basic problem. It puts AI coding usage side by side and supports tools including: - Claude Code - Codex - Gemini CLI - OpenCode Go - Cursor - Kimi - GitHub Copilot It also shows quota and reset information and has notifications for usage thresholds. One interesting difference is that UsageMaster tries to help answer a slightly bigger question: âWhich tool should I use right now?â Thatâs useful when you have several subscriptions and one of them is getting close to its limit. Again, though, itâs a Mac app. ### 5. AI Usage Monitor If youâre looking for something simpler and open source, thereâs also AI Usage Monitor for Windows. It tracks: - Codex - Claude Code - Cursor - Google Antigravity and can display usage through a desktop widget, system tray icon, or compact taskbar-style interface. I actually like the simplicity of this idea. You donât need a giant dashboard. You just want the information somewhere you can see it while coding. Itâs also free and open source. The tradeoff is that itâs currently a Windows-only project, and some of its additional cost-estimation functionality is still described as being in progress. ### 6. Claude Code & Codex Usage Monitor There are also tiny tools that take an even simpler approach. For example, this VS Code extension puts Claude Code and Codex usage directly in the editorâs status bar. You can see things like: 5h usage Weekly usage Time until reset without leaving your editor. Honestly, this can be enough. If you spend your entire day inside VS Code, why open another app? The downside is obvious too. Itâs primarily an editor extension and focuses on fewer providers. Itâs more of a âshow me my usage while I codeâ solution than a complete multi-account desktop monitor. ### So which one should you use? This is where I think the comparison gets interesting. These apps arenât actually identical. Some care about usage analytics. Some care about tokens and costs. Some care about reset times. Some live in your menu bar. Some live inside your editor. And some are designed around multiple accounts. Hereâs how Iâd think about them: The exact feature sets change quickly, so Iâd check each projectâs current documentation before choosing one. ### But hereâs what I really wanted After trying to find these tools, I realized something. I donât really care about another beautiful analytics dashboard. I donât want to stare at graphs showing how many tokens I used last Tuesday. Sometimes I just want three things: 82% left. Resets in 2 hours. Use this account. Thatâs it. Especially when youâre coding. Your attention is already somewhere else. The last thing you want is to stop and become an accountant for your AI subscriptions. ### Multiple accounts make this much more important This is probably the part people donât notice at first. Using three AI coding tools isnât necessarily difficult. Using three tools with multiple accounts is where things get annoying. Maybe you have: Codex Personal Codex Work Claude Personal Claude Work Cursor Personal Now you donât just have usage limits. You have a little collection of usage limits. And each one can reset at a different time. Thatâs where having one quiet place to look becomes genuinely useful. ### The best usage tracker is probably the boring one Thatâs what I keep coming back to. I donât want an AI usage tracker to become another app I have to manage. I donât want to configure it every morning. I donât want another account. I donât want another complicated dashboard. I want to glance at it and go back to coding. Thatâs why I think the future of these tools is actually pretty simple. Not more charts. Not more analytics. Just better context. Which account has room? How much is left? When does it reset? Should I switch? ### AI coding is becoming a multi-tool workflow This is the interesting part. A while ago, developers often picked one AI coding assistant. Now itâs becoming normal to use several. One agent might be great for a refactor. Another might fit your terminal workflow better. Another might be useful for autocomplete. And another might simply have quota available when everything else is exhausted. The tools are becoming interchangeable. But the usage limits arenât. Thatâs why I think small utilities like these are going to become more useful. They sit one layer above the coding agents. They donât replace them. They simply help you manage them. ### Final thought The funny thing is that I never thought AI usage tracking would become something I cared about. I just wanted to code. But once you use multiple coding agents every day, usage becomes part of the workflow. And checking five different places isnât really a workflow. Itâs friction. Maybe the perfect solution isnât the one with the most features. Maybe itâs the one that lets you look once⊠know where you stand⊠and get back to building. Thatâs probably all most of us really want. --- Top Apps for Tracking Multiple Coding Agent Usage and Reset Times was originally published in Dev Genius on Medium, where people are continuing the conversation by highlighting and responding to this story.
MACCODEXCURSOR
CYBERSECURITY AND PRIVACY

I ran both in Docker, added latency, closed a firewall and watched each one fail in its own way Continue reading on Dev Genius »
FIREWALLSCP