Skip to main content

Posts

Keeping SQS and Lambda Timeouts in Sync with Terraform

A Lambda consumer can succeed on a message and the same message can still run twice. Often nothing malfunctioned: two numbers that were never set together are interacting, the queue's visibility timeout and the function's timeout. The reasoning behind how those numbers should relate (including the recommendation of six times the function timeout plus the batching window) is covered in the earlier post, SQS and Lambda: Choosing Visibility Timeout, Retries and Dead-Letter Queue Settings . This one stays on configuration: how to make sure the numbers cannot quietly drift apart. Three settings, edited on different days The function timeout lives on the function. The visibility timeout lives on the queue. The batching window lives on the event source mapping. In a console-driven setup they get changed by different people on different days, each change reasonable in isolation. Lambda does check one relationship: the function timeout must be less than or equal to the queue's v...
Recent posts

Draft-Only AI Agents on Blogger: Why the Credential Can't Be the Boundary

I run a blog agent that creates Blogger drafts and never publishes directly. It runs as an AWS Lambda function packaged as an ARM64 container image, its runtime credentials live in AWS Secrets Manager, and CI/CD authenticates to AWS with OIDC. I read every draft before it goes live. As a description of a workflow, that is fine. As a safety guarantee it is weak, because "a human reviews everything" says nothing about where the system makes publishing impossible. A bad refactor, a misread parameter or a model-generated change to the publishing step could quietly turn drafts into live posts. This post looks at where that boundary can actually be enforced when the target is the Blogger API, why the credential cannot carry it, and where it has to be enforced instead. It also covers what is still rough, because the setup is not frictionless. Where the setup stands today The agent only ever creates drafts, and publishing is a manual step after review. Recently I added logging: ...

SQS and Lambda: Choosing Visibility Timeout, Retries and Dead-Letter Queue Settings

Picture a Lambda function with a 60-second timeout reading from an SQS queue. How long should the queue hide a message once the function has picked it up? The intuitive answer is 60 seconds, maybe a little more. The documented answer is considerably larger, and understanding why matters more than copying the number. This guide walks through the reasoning behind each setting that connects a queue to its consumer, and the failure modes each one is meant to prevent. Three questions drive the decisions. Can a message be processed twice without harm? How long should a genuinely failed message stay hidden before it is retried? And who looks at the dead-letter queue (DLQ), and how long do they have to act? The defaults answer none of these for you. A visibility timeout is a lease, not a limit on your code When a consumer receives a message, SQS hides it for the length of the visibility timeout. If the message is not deleted within that window, it becomes visible again. SQS cannot disting...

Secrets Manager Rotation and AWS Lambda: Designing for Credentials That Change

Most Lambda functions read a secret once during initialization, keep it in a static field and never think about it again. That works until someone turns on automatic rotation. From that moment the value in memory can become outdated while the function is still running, and the symptom is rarely a Secrets Manager error. It shows up as a 401 or a database login failure somewhere downstream, which is easy to mistake for a configuration problem. This guide explains where the problem comes from, which strategies handle it, and what the rotation side needs to get right. The short version: rotation is a design decision for both the code that reads the secret and the code that changes it, not a switch you flip afterwards. Why cached secrets and rotation clash Lambda reuses an execution environment for many invocations, and code outside the handler runs once per environment. That is the right place for SDK clients and the wrong place for a credential that is meant to change. An environment...

Lambda Cold Starts in Serverless .NET: What Actually Helps and What Doesn't

Cold starts are one of the most discussed and least understood performance topics in serverless .NET. Many of the usual tips either address something you cannot control or were true years ago and no longer are. This guide separates the levers that move the number from the ones that mostly add complexity. What a cold start actually contains When Lambda has no warm execution environment available, it creates one. That includes downloading your code, starting the runtime, and running your initialization code. On .NET, the part you can influence most is the runtime start and your own startup logic: loading assemblies, JIT-compiling code, building the dependency injection container and creating SDK clients. The easiest way to see it is the REPORT line Lambda writes to CloudWatch Logs for each invocation. Cold invocations include an Init Duration field. Query that field in CloudWatch Logs Insights to get p50, p95 and p99 for your own function before changing anything. The levers, fro...

Why Dependency Injection in .NET Modernization Is an Architecture Decision, Not a Testing Tool

Dependency injection (DI) is usually sold as a way to make unit tests easier. In a legacy .NET modernization that is the smallest part of its value. The larger value is that DI forces a team to name the contracts between components that were tangled together for years, and once those contracts exist you can replace what sits behind them one piece at a time. This article is organized as the questions that come up when you start, in the order they usually appear. What problem does DI actually surface? Older .NET code often mixes construction, configuration and execution in one method. A routine that sends an email might create an SMTP client, read a connection string from a config file, build the message, log the attempt, retry on failure and update a database row, all inline. You cannot test it without live dependencies, and you cannot change any one of those concerns without touching the others. DI does not fix that code by itself. What it does is ask an uncomfortable question: wh...

Right-Sizing AWS Lambda Memory: A Measurement Runbook Instead of Guessing

Every Lambda function has a memory setting, and most teams pick a round number such as 512 or 1024 MB and never look at it again. That is a missed chance on both cost and speed, because memory is not only about RAM. Lambda allocates CPU and network capacity in proportion to the memory you configure, so the setting also controls how fast the function runs. This article is a short runbook: what to measure, how to test, and how to decide. Why memory also means speed and cost Lambda bills in gigabyte-seconds: memory (in GB) multiplied by billed duration (in seconds), plus a small per-request charge. A function with 1,024 MB that runs for 500 ms uses 0.5 GB-seconds. At 512 MB with the same duration it would use 0.25 GB-seconds, half the compute cost. But the duration will not necessarily stay the same, because CPU scales with memory. AWS documents that roughly 1.8 GB corresponds to one full vCPU, and the maximum of 10,240 MB provides up to six. A CPU-bound function (parsing, serializat...