Senior 6 min · June 25, 2026

Serverless Architecture: When It Works, When It Breaks, and How to Survive Both

Serverless architecture explained with real production patterns, cold start mitigation, and the exact gotchas that burn teams at scale..

N
Naren Founder & Principal Engineer

20+ years shipping large-scale distributed systems. Notes here come from systems that actually shipped.

Follow
Production
production tested
June 25, 2026
last updated
145
articles · all by Naren
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Serverless lets you run code without provisioning or managing servers. Your code is packaged as functions, triggered by HTTP requests, database changes, or queue messages. The provider scales from zero to thousands of concurrent executions automatically. You pay per invocation and duration, not per allocated instance.

✦ Definition~90s read
What is Serverless Architecture?

Serverless architecture is a cloud execution model where the cloud provider dynamically manages the allocation and provisioning of servers. You write functions that run in stateless containers, triggered by events, and you pay only for the compute time you consume — no idle capacity.

Think of serverless like a taxi service.
Plain-English First

Think of serverless like a taxi service. You don't own the car, you don't pay for parking, and you don't pay the driver when you're not riding. You just call a ride when you need it, pay for the distance you travel, and get out. The taxi company handles all the maintenance, fuel, and routing. If a thousand people need a ride at once, they send a thousand cars — you never think about fleet management.

Serverless is the most oversold and underdelivered architecture pattern in cloud computing. Everyone promises infinite scale and zero ops. The reality? Cold starts kill your p99 latency, vendor lock-in is a trap, and debugging is like finding a needle in a haystack while blindfolded. But when you get it right — when you design for its strengths and work around its weaknesses — it's the most cost-effective way to run event-driven workloads at scale.

The problem serverless solves is simple: traditional servers waste money on idle capacity. You pay for a 24/7 VM that sits at 5% CPU most of the time. Serverless flips that — you pay only when your code runs. But the hidden cost is complexity: you trade server management for function orchestration, state management, and a whole new class of failure modes.

By the end of this article, you'll know exactly when to use serverless, how to handle cold starts, how to avoid the 15-minute timeout trap, and what to do when your functions start timing out under load. You'll also get the real-world debugging commands and configs that separate production engineers from tutorial readers.

Why Serverless Exists: The Idle Server Tax

Before serverless, you paid for servers that sat idle 90% of the time. A typical web service handles peak traffic for 2 hours a day. The other 22 hours, you're burning money on idle CPU and memory. Serverless eliminates that tax. You pay only for the milliseconds your code actually runs. But that efficiency comes with strings attached: your code must be stateless, short-lived, and event-driven. If your workload doesn't fit that model, serverless will cost you more in complexity than it saves in compute.

The real win is for variable or unpredictable traffic. Batch jobs that run once a day? Perfect. APIs that get 10 requests most of the time but spike to 10,000 during a sale? Serverless handles that without any capacity planning. But if you have steady-state traffic 24/7, a cheap VM or container might be cheaper and simpler.

serverless-cost-comparison.shDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// io.thecodeforge — DevOps tutorial

# Compare cost of a t3.medium EC2 (2 vCPU, 4GB) vs Lambda for a workload
# Assumptions: 10M requests/month, 200ms average duration, 128MB memory

# EC2 cost (us-east-1, on-demand, 24/7):
echo "EC2 monthly: $30.14"

# Lambda cost (us-east-1, 128MB, 200ms, 10M invocations):
echo "Lambda monthly: $10.83"

# But add API Gateway, CloudWatch logs, and data transfer:
echo "Total serverless: ~$25/month"

# Break-even point: if your Lambda runs more than 1.2M seconds/month (about 40% CPU utilization on t3.medium), EC2 is cheaper.
Output
EC2 monthly: $30.14
Lambda monthly: $10.83
Total serverless: ~$25/month
Senior Shortcut:
Use the AWS Lambda Cost Calculator (or equivalent) before committing. Many teams move to serverless and see their bill go up because they have steady traffic and didn't account for API Gateway costs ($3.50 per million requests) and CloudWatch logs ($0.50 per GB ingested).
Serverless VPC Cold Start Gotcha — 30s Timeout THECODEFORGE.IO Serverless VPC Cold Start Gotcha — 30s Timeout Flow from request to timeout due to VPC cold start latency API Gateway Request Incoming HTTP request triggers Lambda Lambda Cold Start New execution environment initialization VPC ENI Attachment Elastic Network Interface provisioning 30s Timeout Lambda timeout before ENI ready Request Failure Client receives 503/504 error ⚠ VPC cold start can exceed Lambda timeout limit Use VPC endpoints or provisioned concurrency to avoid THECODEFORGE.IO
thecodeforge.io
Serverless VPC Cold Start Gotcha — 30s Timeout
Serverless Architecture

Cold Starts: The Hidden Latency Tax

Cold starts are the #1 performance killer in serverless. When a function hasn't been invoked for a while (typically 5-15 minutes depending on the provider), the runtime shuts down the container. The next invocation must download your code, initialize the runtime, run any global initialization code, and then execute your handler. That adds 100ms to 10+ seconds depending on runtime, package size, and dependencies.

Why does this happen? Providers reuse containers for subsequent invocations to save time. But they don't keep them around forever — that would waste memory. The exact timeout is undocumented and varies. In practice, you'll see cold starts after 5-15 minutes of inactivity. The fix is provisioned concurrency: keep a pool of pre-warmed instances ready to serve requests instantly. But that costs money — you pay for the idle time. It's a trade-off between latency and cost.

For Java and .NET, cold starts are brutal because of JVM/CLR startup time. Python and Node.js are faster. Go and Rust are fastest because they compile to native binaries. If you need sub-100ms p99, use Go or Rust with provisioned concurrency.

measure-cold-start.shDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// io.thecodeforge — DevOps tutorial

# Measure cold start duration using CloudWatch Logs Insights
# Run this query to find cold starts (initialization duration > 0)

fields @timestamp, @duration, @initDuration
| filter @initDuration > 0
| sort @timestamp desc
| limit 20

# Output shows cold start init times. Average them:
# stats avg(@initDuration) by @logGroup

# To see warm invocations:
fields @timestamp, @duration
| filter @initDuration = 0
| stats avg(@duration) as avg_warm_duration
Output
| @timestamp | @duration | @initDuration |
|----------------------|-----------|---------------|
| 2024-01-15T10:00:00 | 120 | 3500 |
| 2024-01-15T10:05:00 | 115 | 0 |
| 2024-01-15T10:10:00 | 118 | 0 |
| 2024-01-15T10:15:00 | 130 | 4200 |
Production Trap:
Never assume your function is always warm. I've seen a payment processing service fail during a flash sale because the function had been idle for 20 minutes. The first request hit a 10-second cold start, the API Gateway timed out, and the client retried — causing duplicate charges. Always design for cold starts: use idempotency keys and set realistic timeouts.
Cold Start LifecycleTHECODEFORGE.IOCold Start LifecycleFrom idle to invocationFunction IdleContainer shut down after 5-15 minDownload CodeFetch package from storageInit RuntimeStart Node.js/Python/JavaRun HandlerExecute user codeReturn ResponseLatency spike: 100ms–5s⚠ Warm functions respond in ms; cold adds seconds of latencyTHECODEFORGE.IO
thecodeforge.io
Cold Start Lifecycle
Serverless Architecture

Statelessness: You Have No Home

Serverless functions are stateless by design. You can't store data in local memory or disk and expect it to be there on the next invocation. The container might be reused, but it might also be destroyed at any time. Never assume local state persists. This is the #1 cause of subtle bugs in serverless apps.

What goes wrong? Developers cache database connections or API tokens in global variables, assuming they'll be reused. They are — until the container is recycled. Then you get a connection timeout on the next request because the old connection was closed. The fix is to always check connections before using them, or use connection pooling libraries that handle reconnection.

For state that must survive across invocations, use external stores: DynamoDB for key-value, S3 for files, ElastiCache for caching. But be aware of the latency hit — every external call adds network overhead. Batch your operations and use async patterns where possible.

stateless-lambda.pyDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// io.thecodeforge — DevOps tutorial

import boto3
import os
from botocore.config import Config

# BAD: global variable assumes persistence
db_connection = None

def bad_handler(event, context):
    global db_connection
    if not db_connection:
        db_connection = create_connection()  # Expensive init
    # db_connection might be stale after container recycle
    return db_connection.query(...)

# GOOD: use connection pool with health check
def good_handler(event, context):
    # Create a new client each time (cheap)
    dynamodb = boto3.resource('dynamodb', config=Config(connect_timeout=5, read_timeout=5))
    table = dynamodb.Table(os.environ['TABLE_NAME'])
    # Use table directly — boto3 handles retries
    response = table.get_item(Key={'id': event['id']})
    return response['Item']
Output
No output — this is a code pattern, not a script.
Senior Shortcut:
Use environment variables for config, not local files. Lambda /tmp directory is 512MB and persists across warm invocations, but don't rely on it for critical data. Use it for caching large objects that you can regenerate.

Timeouts: The 15-Minute Wall

Every serverless provider has a maximum execution timeout. AWS Lambda: 15 minutes. Azure Functions: 10 minutes (or 60 with premium plan). Google Cloud Functions: 9 minutes. If your function runs longer, it gets killed. Period.

This is fine for quick API calls or data transformations. But if you have a long-running task — processing a large file, generating a report, training a model — you can't do it in a single function. The solution is to break the work into smaller chunks and chain them using step functions, queues, or pub/sub.

For example, instead of processing a 1GB CSV in one function, split it into 100 chunks, send each to an SQS queue, and have a function process each chunk. Use a step function to coordinate and aggregate results. This also gives you better scalability and fault tolerance — if one chunk fails, you only reprocess that chunk, not the whole file.

step-function-definition.jsonDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// io.thecodeforge — DevOps tutorial

{
  "Comment": "Process large CSV in chunks",
  "StartAt": "SplitFile",
  "States": {
    "SplitFile": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SplitCSV",
      "Next": "ProcessChunks"
    },
    "ProcessChunks": {
      "Type": "Map",
      "Iterator": {
        "StartAt": "ProcessChunk",
        "States": {
          "ProcessChunk": {
            "Type": "Task",
            "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ProcessChunk",
            "End": true
          }
        }
      },
      "Next": "AggregateResults"
    },
    "AggregateResults": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:Aggregate",
      "End": true
    }
  }
}
Output
Step function executes: SplitFile (2s) -> ProcessChunks (parallel, each 10s) -> AggregateResults (1s). Total time: ~13s, well under 15 min.
Never Do This:
Don't set your function timeout to 15 minutes and hope it finishes. If it times out, you get no partial results, and you've wasted 15 minutes of compute. Always design for idempotent retries and checkpoint progress to an external store (DynamoDB, S3).

Concurrency and Throttling: The Herd Problem

Serverless scales by running multiple instances of your function in parallel. AWS Lambda defaults to 1000 concurrent executions per account. If you exceed that, new invocations get throttled with a 429 error. This is a feature, not a bug — it protects your downstream resources from being overwhelmed.

But here's the trap: if you have a burst of traffic, say 5000 requests at once, the first 1000 succeed, and the next 4000 get throttled. Those throttled requests might be retried by the client, creating a thundering herd that keeps hitting your limit. The fix is to use a queue (SQS) to buffer requests and have Lambda pull from the queue at a controlled rate. This decouples the request rate from the processing rate.

Another gotcha: if your function calls a downstream API that has its own rate limits, you need to implement concurrency limits at the function level. Use reserved concurrency to cap the number of concurrent executions. This prevents your function from overwhelming a fragile downstream service.

reserved-concurrency.tfDEVOPS
1
2
3
4
5
6
7
8
9
10
11
// io.thecodeforge — DevOps tutorial

# Terraform: set reserved concurrency to protect downstream API
resource "aws_lambda_function" "api_caller" {
  function_name = "api-caller"
  # ... other config ...
  reserved_concurrent_executions = 10  # Max 10 concurrent calls
}

# Without reserved concurrency, Lambda could launch 1000 instances
# and all hit the downstream API at once, causing 429s.
Output
Terraform apply creates the function with concurrency limit.
Interview Gold:
Q: How do you handle a sudden spike in traffic that exceeds Lambda concurrency limits? A: Use SQS as a buffer. Set the Lambda function's batch size to 1 and attach it to the queue. The queue absorbs the spike, and Lambda processes at its own pace. This also gives you a dead-letter queue for failed messages.

Vendor Lock-In: The Golden Handcuffs

Serverless is the most vendor-locked architecture you can choose. Your functions depend on provider-specific services: AWS Lambda + API Gateway + DynamoDB + SQS + Step Functions. Moving to another cloud means rewriting everything. The abstractions are leaky — each provider has different limits, timeouts, and behaviors.

Mitigation strategies: use the Serverless Framework or AWS SAM for infrastructure as code — at least you can redeploy. Abstract your business logic from the cloud SDK as much as possible. Use environment variables for all provider-specific config. But be honest: if you're all-in on serverless, you're all-in on that cloud. Plan for it.

For multi-cloud or hybrid scenarios, consider container-based solutions like AWS Fargate or Google Cloud Run. They give you some serverless benefits (no server management) but with more portability. Or use Knative on Kubernetes for a truly portable serverless platform.

serverless-framework.ymlDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// io.thecodeforge — DevOps tutorial

# serverless.yml — abstract provider config
service: my-service

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  environment:
    TABLE_NAME: !Ref MyTable

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get

resources:
  Resources:
    MyTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:service}-${sls:stage}-table
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        BillingMode: PAY_PER_REQUEST
Output
Deploy with `sls deploy`. Creates Lambda, API Gateway, DynamoDB table.
Production Trap:
Don't use provider-specific features like AWS Lambda's recursive loop detection or Azure Durable Functions unless you're committed. I've seen teams rewrite entire systems because they wanted to switch from AWS to GCP. The migration cost often exceeds any savings from serverless.

Debugging: Finding Needles in a Serverless Haystack

Debugging serverless is harder than debugging a monolith. You can't SSH into a container. You can't attach a debugger. You rely entirely on logs and distributed tracing. If you don't set up structured logging and tracing from day one, you'll be blind in production.

Use CloudWatch Logs (or equivalent) with structured JSON logging. Include request IDs, correlation IDs, and timing information. Use AWS X-Ray or OpenTelemetry for distributed tracing across functions and downstream services. Set up alarms on error rates, duration, and throttles.

For local testing, use the SAM CLI or Serverless Framework's offline plugin. But remember: local emulation is never perfect. Cold start behavior, IAM permissions, and network latency are different in production. Always test in a staging environment that mirrors production.

structured-logging.pyDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// io.thecodeforge — DevOps tutorial

import json
import os
import time

def handler(event, context):
    start_time = time.time()
    request_id = context.aws_request_id
    
    # Structured log
    print(json.dumps({
        "level": "INFO",
        "request_id": request_id,
        "event_type": event.get('httpMethod', 'UNKNOWN'),
        "path": event.get('path', ''),
        "duration_ms": 0,  # Will be updated at end
        "cold_start": getattr(context, 'cold_start', False)
    }))
    
    # Business logic
    result = process_event(event)
    
    duration = int((time.time() - start_time) * 1000)
    print(json.dumps({
        "level": "INFO",
        "request_id": request_id,
        "duration_ms": duration,
        "status": "SUCCESS"
    }))
    
    return {
        "statusCode": 200,
        "body": json.dumps(result)
    }
Output
CloudWatch Logs shows structured JSON entries that can be queried with Logs Insights.
Senior Shortcut:
Add a cold_start attribute to your context object. Set it to True on first invocation, False on subsequent. Log it. Then you can filter logs to see only cold starts and measure their impact on latency.

When Not to Use Serverless

Serverless is not a silver bullet. Avoid it when
  • You have steady-state, predictable traffic 24/7. A cheap VM or container will be cheaper and simpler.
  • You need low latency (<10ms p99). Cold starts and network overhead make this hard.
  • You have long-running processes (>15 minutes). You'll need to orchestrate multiple functions, adding complexity.
  • You need to maintain stateful WebSocket connections. Serverless functions are ephemeral.
  • You're building a real-time system with sub-millisecond requirements. Use dedicated servers or FPGAs.
  • Your team has no experience with distributed systems. Serverless adds complexity that a monolith doesn't.

For startups with unpredictable traffic, serverless is often a great fit. For enterprises with stable workloads, it's often a cost increase. Do the math before committing.

decision-flow.shDEVOPS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// io.thecodeforge — DevOps tutorial

# Decision flow for serverless vs containers

echo "Is traffic predictable and steady?"
read answer
if [ "$answer" == "yes" ]; then
    echo "Use containers (ECS, EKS, or plain EC2)"
else
    echo "Is latency requirement < 100ms p99?"
    read answer
    if [ "$answer" == "yes" ]; then
        echo "Use provisioned concurrency or containers"
    else
        echo "Serverless is a good fit"
    fi
fi
Output
Interactive script guiding decision.
Interview Gold:
Q: When would you choose AWS Fargate over Lambda? A: When you need consistent low latency, long-running tasks, or want to avoid cold starts. Fargate runs containers without managing servers, but you pay for the container even when idle. Lambda is cheaper for bursty, short-lived workloads.
Serverless vs. TraditionalTHECODEFORGE.IOServerless vs. TraditionalWhen to choose eachServerless WinsSpiky traffic with long idleRapid prototyping & MVPsEvent-driven workloadsMicro-batch processingTraditional WinsSteady 24/7 trafficSub-10ms latency neededLong-running tasks >15 minTight cost control on VMsServerless shines on bursts; steady loads are cheaper on VMsTHECODEFORGE.IO
thecodeforge.io
Serverless vs. Traditional
Serverless Architecture
● Production incidentPOST-MORTEMseverity: high

The 15-Second Cold Start That Killed Our API

Symptom
After 10 minutes of no traffic, the first request to our user-service API took 15 seconds to respond. Subsequent requests were 50ms. Customers saw timeouts and retried, causing a thundering herd.
Assumption
We assumed it was a database connection pool issue — maybe the RDS proxy was closing idle connections.
Root cause
Lambda cold start. Our function loaded a 50MB ML model from S3 on every cold start. The Lambda runtime (Node.js) also had to initialize the AWS SDK and establish a database connection. Total cold start time: 14.8 seconds. The API Gateway timeout was 30 seconds, so the request eventually succeeded, but the client retried after 5 seconds, causing duplicate writes.
Fix
Moved the ML model to Lambda layers (reduced load time by 40%). Enabled provisioned concurrency with 5 warm instances. Set the database connection to lazy initialization with a 500ms timeout. Cold start dropped to 800ms.
Key lesson
  • Always measure cold start duration under realistic conditions before going to production.
  • Provisioned concurrency is not optional for latency-sensitive APIs.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
Function times out after 29 seconds (Lambda default timeout is 3s, but you changed it to 30s and it still times out)
Fix
1. Check CloudWatch Logs for the exact error: 'Task timed out after 30.00 seconds'. 2. Increase timeout to 60s in function config. 3. If still timing out, split the work into smaller chunks using Step Functions or SQS. 4. Add logging at each step to identify the bottleneck.
Symptom · 02
Error: 'Rate exceeded' when invoking Lambda (HTTP 429)
Fix
1. Check your account concurrency limit in Service Quotas. 2. Check if you have reserved concurrency set too low. 3. Implement exponential backoff in the caller. 4. Use SQS to buffer requests and decouple invocation rate.
Symptom · 03
Function returns stale data or fails intermittently
Fix
1. Check if you're caching data in global variables. 2. Verify that external service connections are re-established on each invocation. 3. Look for 'Connection pool exhausted' errors in logs. 4. Use environment variables for config, not hardcoded values.
★ Serverless Architecture Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
Cold start latency spike — p99 goes from 50ms to 5s after idle period
Immediate action
Check if provisioned concurrency is enabled
Commands
aws lambda get-provisioned-concurrency-config --function-name my-function --qualifier prod
aws lambda put-provisioned-concurrency-config --function-name my-function --qualifier prod --provisioned-concurrent-executions 5
Fix now
Enable provisioned concurrency with at least your baseline traffic count. Monitor costs.
Function throttled — 429 errors in API Gateway logs+
Immediate action
Check current concurrency usage
Commands
aws cloudwatch get-metric-statistics --namespace AWS/Lambda --metric-name ConcurrentExecutions --statistics Sum --period 60 --start-time $(date -u -d '5 minutes ago' +%Y-%m-%dT%H:%M:%SZ)
aws lambda get-account-settings | jq '.AccountLimit'
Fix now
Request a concurrency limit increase via Service Quotas. Implement SQS buffering.
Function times out — 'Task timed out after X seconds'+
Immediate action
Check current timeout setting
Commands
aws lambda get-function-configuration --function-name my-function | jq '.Timeout'
aws lambda update-function-configuration --function-name my-function --timeout 60
Fix now
Increase timeout to a reasonable value (max 900s). If still timing out, refactor into smaller functions.
Function fails with 'AccessDeniedException' when accessing S3 or DynamoDB+
Immediate action
Check IAM role permissions
Commands
aws iam get-role --role-name my-function-role | jq '.Role.AssumeRolePolicyDocument'
aws iam list-attached-role-policies --role-name my-function-role
Fix now
Attach the necessary policy (e.g., AmazonS3ReadOnlyAccess) to the role. Use least privilege.
Feature / AspectAWS LambdaAWS Fargate
Execution timeout15 minutesNo limit (task-based)
Cold start100ms-10sNone (container always warm)
PricingPer invocation + durationPer hour (vCPU + memory)
StateStatelessCan be stateful (local disk)
ScalingAuto from 0 to 1000sAuto but requires config
Best forBursty, event-drivenSteady-state, long-running

Key takeaways

1
Serverless eliminates idle server costs but introduces cold start latency, statelessness constraints, and vendor lock-in.
2
Always measure cold start duration in production-like conditions before going live. Use provisioned concurrency for latency-sensitive functions.
3
Design for failure
use idempotency keys, dead-letter queues, and structured logging from day one.
4
Serverless is not cheaper for steady-state workloads. Do the math before migrating.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does AWS Lambda handle concurrent requests when the function is alre...
Q02SENIOR
When would you choose AWS Lambda over AWS Fargate for a production API?
Q03SENIOR
What happens to a Lambda function's /tmp directory after the function fi...
Q04JUNIOR
What is a cold start and how do you mitigate it?
Q05SENIOR
Your Lambda function is idempotent, but you're seeing duplicate records ...
Q06SENIOR
How would you design a serverless system that processes a 10GB file ever...
Q01 of 06SENIOR

How does AWS Lambda handle concurrent requests when the function is already processing one? Does it spawn a new container or queue the request?

ANSWER
Lambda spawns a new container for each concurrent request, up to your account concurrency limit. It does not queue requests — if the limit is reached, new requests get a 429 error. You must use SQS or another buffer to queue requests if you need to control concurrency.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
What is serverless architecture in simple terms?
02
What's the difference between serverless and containers?
03
How do I handle cold starts in serverless?
04
Can serverless handle long-running processes?
N
Naren Founder & Principal Engineer

20+ years shipping large-scale distributed systems. Notes here come from systems that actually shipped.

Follow
Verified
production tested
June 25, 2026
last updated
145
articles · all by Naren
🔥

That's Architecture. Mark it forged?

6 min read · try the examples if you haven't

Previous
Location-Based Services
14 / 17 · Architecture
Next
Service Mesh