
Zero to Production: Building a Budget-Friendly Serverless AI Microservice with Amazon Bedrock & AWS Lambda
Build a cost-effective, auto-scaling generative AI microservice using Amazon Bedrock, AWS Lambda, and API Gateway.
Zero to Production: Building a Budget-Friendly Serverless AI Microservice with Claude Haiku 5.5, Amazon Bedrock & AWS Lambda
Building generative AI applications does not require Kubernetes clusters, dedicated GPU instances, or a custom model-serving infrastructure. For many application workloads, AWS serverless services provide a practical way to deploy intelligent features while keeping operational overhead low.
In this guide, we will build a text-intelligence API using Amazon API Gateway, AWS Lambda, and Amazon Bedrock, powered by the newly released Claude Haiku 5.5. The implementation includes least-privilege IAM permissions, request validation, bounded inference, token-usage tracking, and Bedrock streaming response handling.
The goal is to create a cost-conscious API that can evolve from a prototype into a production service without requiring a complete architectural redesign.
The problemAI prototypes often demonstrate model capabilities but overlook authorization, request validation, inference quotas, observability, and cost management. These omissions become significant when a prototype starts serving real users.
The approachPut a managed API in front of a serverless compute layer, restrict model access through IAM, limit input and output consumption, and monitor real inference usage rather than relying on estimates alone.
1. Why Claude Haiku 5.5?
Anthropic announced Claude Haiku 5.5 on October 7, 2026, and AWS announced its availability on Amazon Bedrock the same day. The model targets high-volume, cost-sensitive, and latency-sensitive workloads such as classification, summarization, information extraction, and in-app assistants.
According to Anthropic, Haiku 5.5 costs around 75% less to run than Haiku 4.5 for most tasks, on average. Its published per-token pricing is also substantially lower, although actual savings depend on tokenization, workload characteristics, and inference configuration.
Sources: AWS launch announcement and Anthropic's Haiku 5.5 announcement .
Model characteristics
| Property | Claude Haiku 5.5 |
|---|---|
| Model launch date | October 7, 2026 |
| Context window | Up to 1 million tokens |
| Maximum output | Up to 128,000 tokens |
| Amazon Bedrock endpoint | bedrock-runtime |
| Converse API | Supported |
| ConverseStream API | Supported |
| Reasoning controls | Adaptive thinking and configurable effort levels |
| Primary use cases | Classification, summarization, extraction, and latency-sensitive applications |
These are model capabilities, not recommended defaults for every application. Our API will deliberately use a much smaller output limit because its tasks do not require long-form generation.
The model's context window also does not determine the maximum request size that your application should accept. Application limits, service quotas, latency objectives, and budget constraints still matter.
See the official Amazon Bedrock model card for the current feature matrix and supported inference options.
2. Architecture Overview
The architecture has three primary components:
- Amazon API Gateway: Exposes a managed HTTPS endpoint and provides API-level throttling and usage controls.
- AWS Lambda: Validates requests, selects an approved task, and invokes the model using Python 3.12.
- Amazon Bedrock: Provides managed access to Claude Haiku 5.5 through the ConverseStream API.
Amazon CloudWatch Logs captures application errors and token-usage metrics.
Request flow
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
36
37
38
39
40
41
┌───────────────────────────────────┐
│ Web / Mobile Client │
└─────────────────┬─────────────────┘
│
│ HTTPS + API Key
▼
┌───────────────────────────────────┐
│ Amazon API Gateway │
│ │
│ API Key / Usage Controls │
│ Request Throttling │
└─────────────────┬─────────────────┘
│
│ Lambda Proxy Integration
▼
┌───────────────────────────────────┐
│ AWS Lambda │
│ Python 3.12 │
│ │
│ Request Validation │
│ Task Selection │
│ Prompt Construction │
│ Response Processing │
└─────────────────┬─────────────────┘
│
│ IAM Execution Role
▼
┌───────────────────────────────────┐
│ Amazon Bedrock │
│ │
│ ConverseStream API │
│ Claude Haiku 5.5 Inference │
└───────────────────────────────────┘
│
▼
┌───────────────────────────────────┐
│ Amazon CloudWatch │
│ │
│ Logs / Errors / Usage │
└───────────────────────────────────┘Why this stack?
| Capability | Engineering benefit |
|---|---|
| On-demand execution | No continuously running Lambda compute instances are required. |
| Managed inference | AWS manages the underlying model-serving infrastructure. |
| Automatic scaling | Lambda can scale with traffic within account concurrency and service quotas. |
| IAM authorization | The execution role controls which model resources the application can invoke. |
| Client isolation | Browser and mobile clients do not need AWS credentials. |
| Model configurability | The model ID can be changed through deployment configuration. |
| Cost visibility | Token-usage logging helps explain inference consumption. |
Cost qualification: Serverless minimizes continuously running application compute, but it does not make every request free. Model inference, API requests, logging, networking, and other services can still incur charges.
3. IAM Policy: Principle of Least Privilege
The Lambda execution role should contain only the permissions required by the application.
For this example, we will use the global cross-Region inference profile for Claude Haiku 5.5:
1
global.anthropic.claude-haiku-5-5Set
MODEL_ID to the appropriate inference profile for your deployment. Global inference provides routing flexibility, but it should not be used when your data-residency requirements prohibit processing outside a specified geography.IAM execution-role policy
The following JSON policy is an example for a deployment in
us-east-1. Replace 111122223333 with your AWS account ID and verify the inference-profile ARN and model-resource ARNs for the account and Region you use.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeApprovedHaiku55Model",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": [
"arn:aws:bedrock:us-east-1:111122223333:inference-profile/global.anthropic.claude-haiku-5-5",
"arn:aws:bedrock:*::foundation-model/anthropic.claude-haiku-5-5"
]
}
]
}Understanding the permissions
bedrock:InvokeModel allows standard model invocation.bedrock:InvokeModelWithResponseStream allows streaming model invocation through the ConverseStream API.The inference-profile ARN restricts requests to the selected inference profile.
The foundation-model ARN covers the underlying model resource required for cross-Region inference.
The example uses a Region wildcard for the foundation-model ARN because a global inference profile may route requests across multiple destination Regions. Replace the wildcard with an explicit list of supported destination-region ARNs where your security and governance requirements demand narrower scoping.
Do not assume the example policy will work unchanged with every model profile. Check the IAM requirements for the exact inference profile you select.
Security note: IAM policy documents use JSON and cannot contain inline comments. The example above is valid JSON. Add only the permissions necessary for your actual deployment, and test the policy before production release.
For basic Lambda logging, attach the AWS managed policy
AWSLambdaBasicExecutionRole to the execution role. This provides the permissions required to write logs to CloudWatch Logs.Official references:
4. Lambda Handler: Python 3.12
The API will expose three operations:
| Task | Behavior |
|---|---|
| summarize | Summarizes the input in no more than three sentences. |
| sentiment | Classifies the input as positive, negative, or neutral. |
| keywords | Extracts up to eight relevant keywords. |
The client supplies a task name and input text. The system prompt remains server-controlled, avoiding an interface in which clients can freely replace the application's instructions.
Configuration
Set the following environment variables in the Lambda configuration:
| Variable | Example | Purpose |
|---|---|---|
| MODEL_ID | global.anthropic.claude-haiku-5-5 | Selects the inference profile. |
| BEDROCK_REGION | us-east-1 | Configures the Bedrock runtime client. |
| MAX_INPUT_CHARS | 8000 | Limits accepted input size. |
| MAX_OUTPUT_TOKENS | 512 | Limits generated output. |
The example is configured for the global profile from
us-east-1. Before deployment, confirm regional availability, profile permissions, and any data-residency requirements.Dependencies
The Lambda Python runtime includes Boto3, but its bundled version may not always contain the newest service-model definitions. For reproducible deployments, package a tested SDK version with your application or use a maintained dependency layer.
1
pip install boto3 -t package/Package the handler and dependency directory according to your Lambda deployment format. Pin and test the dependency version in your build pipeline rather than relying on an unverified SDK version.
lambda_function.py
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
import json
import logging
import os
import boto3
from botocore.config import Config
from botocore.exceptions import BotoCoreError, ClientError, ReadTimeoutError
# Keep deployment-specific settings configurable.
MODEL_ID = os.environ.get(
"MODEL_ID",
"global.anthropic.claude-haiku-5-5",
)
BEDROCK_REGION = os.environ.get(
"BEDROCK_REGION",
os.environ.get("AWS_REGION", "us-east-1"),
)
MAX_INPUT_CHARS = int(
os.environ.get("MAX_INPUT_CHARS", "8000")
)
MAX_OUTPUT_TOKENS = int(
os.environ.get("MAX_OUTPUT_TOKENS", "512")
)
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Best practice: initialize the SDK client outside the handler.
# Warm Lambda invocations can reuse the client and its connections.
bedrock = boto3.client(
"bedrock-runtime",
region_name=BEDROCK_REGION,
config=Config(
connect_timeout=3,
read_timeout=20,
# One SDK attempt avoids retrying a slow request beyond
# the intended Lambda execution window.
retries={
"total_max_attempts": 1,
"mode": "standard",
},
),
)
# Security measure: expose a controlled set of operations.
# Clients select an operation but cannot supply arbitrary system prompts.
SYSTEM_PROMPTS = {
"summarize": (
"You are a precise summarizer. "
"Summarize the supplied text in at most three sentences."
),
"sentiment": (
"Classify the sentiment of the supplied text as positive, "
"negative, or neutral. Reply with one word only."
),
"keywords": (
"Extract up to eight relevant keywords from the supplied text. "
"Return a comma-separated list only."
),
}
def make_response(status_code, body):
"""Create a standard API Gateway proxy response."""
return {
"statusCode": status_code,
"headers": {
"Content-Type": "application/json",
"Cache-Control": "no-store",
},
"body": json.dumps(body),
}
def lambda_handler(event, context):
# Step 1: parse and validate the request before using the model.
try:
raw_body = event.get("body") or "{}"
if isinstance(raw_body, str):
payload = json.loads(raw_body)
elif isinstance(raw_body, dict):
# Also supports direct invocation and unit tests.
payload = raw_body
else:
return make_response(
400,
{"error": "Request body must be a JSON object."},
)
except json.JSONDecodeError:
return make_response(
400,
{"error": "Body must contain valid JSON."},
)
if not isinstance(payload, dict):
return make_response(
400,
{"error": "Request body must be a JSON object."},
)
task = payload.get("task", "summarize")
text = payload.get("text", "")
# Reject unknown operations before an inference request is made.
if not isinstance(task, str) or task not in SYSTEM_PROMPTS:
return make_response(
400,
{
"error": (
f"Task must be one of {sorted(SYSTEM_PROMPTS)}"
)
},
)
if not isinstance(text, str) or not text.strip():
return make_response(
400,
{"error": "A non-empty text field is required."},
)
text = text.strip()
# Bound request size to reduce excessive input consumption.
# Character count is an application guardrail, not a token count.
if len(text) > MAX_INPUT_CHARS:
return make_response(
413,
{
"error": (
f"Text exceeds {MAX_INPUT_CHARS} characters."
)
},
)
# Step 2: invoke Claude Haiku 5.5 with the ConverseStream API.
try:
result = bedrock.converse_stream(
modelId=MODEL_ID,
system=[
{"text": SYSTEM_PROMPTS[task]}
],
messages=[
{
"role": "user",
"content": [
{"text": text}
],
}
],
inferenceConfig={
# Bound generated output to control cost and latency.
"maxTokens": MAX_OUTPUT_TOKENS,
"temperature": 0.2,
},
)
chunks = []
usage = {}
# Read Bedrock's event stream and collect text fragments.
# The client will receive a buffered JSON response below.
for stream_event in result["stream"]:
if "contentBlockDelta" in stream_event:
delta = stream_event["contentBlockDelta"].get(
"delta", {}
)
chunks.append(delta.get("text", ""))
elif "metadata" in stream_event:
usage = stream_event["metadata"].get("usage", {})
except ReadTimeoutError:
logger.warning(
"Bedrock read timeout: request_id=%s",
context.aws_request_id,
)
return make_response(
504,
{"error": "The model request timed out."},
)
except ClientError as error:
error_code = error.response.get(
"Error", {}
).get("Code", "Unknown")
# Log the service error code, not the user's input text.
logger.error(
"Bedrock invocation failed: code=%s request_id=%s",
error_code,
context.aws_request_id,
)
if error_code in {
"ThrottlingException",
"ServiceQuotaExceededException",
}:
return make_response(
429,
{"error": "The model is busy. Retry later."},
)
return make_response(
502,
{"error": "The upstream model request failed."},
)
except BotoCoreError:
logger.exception(
"Bedrock SDK failure: request_id=%s",
context.aws_request_id,
)
return make_response(
502,
{"error": "Unable to complete the model request."},
)
# Step 3: record usage so request costs can be analyzed.
# Never log the full prompt or generated content by default.
logger.info(
"request_id=%s task=%s input_tokens=%s output_tokens=%s",
context.aws_request_id,
task,
usage.get("inputTokens"),
usage.get("outputTokens"),
)
return make_response(
200,
{
"task": task,
"result": "".join(chunks).strip(),
"usage": usage,
"request_id": context.aws_request_id,
},
)Implementation notes
Client reuse: The Bedrock runtime client is initialized outside the handler so warm invocations can reuse it.
Request validation: Invalid JSON, unknown task names, empty input, and oversized requests are rejected before calling the model.
Prompt control: The server defines the allowed operations and their prompts. This is a safer boundary than accepting arbitrary system prompts from clients, although it does not replace broader prompt-injection defenses.
Inference limits: The output-token cap helps control model costs. The input character limit helps constrain request size, but actual token usage depends on the tokenizer and the system prompt.
Controlled errors: AWS exception details are logged in a restricted operational environment and are not sent directly to public clients.
Token observability: Usage is recorded without writing the actual prompt or generated response to CloudWatch Logs.
The example deliberately uses a single SDK attempt and a finite read timeout. Tune these settings using measured latency and actual service quotas. If retries are introduced, ensure the combined retry and timeout budgets fit within the API's execution window.
This sample also leaves Claude Haiku 5.5's model-specific reasoning-effort controls at their defaults. For classification and extraction tasks, benchmark different supported effort settings before enabling more expensive reasoning behavior. Check the current model card for the supported parameters.
5. Test the API
Assume that the REST API has been deployed to the
prod stage and that the API key is associated with an appropriate usage plan.Example request
1
2
3
4
5
6
7
8
curl -X POST \
"https://<api-id>.execute-api.<region>.amazonaws.com/prod/analyze" \
-H "x-api-key: <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"task": "sentiment",
"text": "The deploy took four minutes and nothing broke. Great day."
}'Example response
1
2
3
4
5
6
7
8
9
10
{
"task": "sentiment",
"result": "positive",
"usage": {
"inputTokens": 52,
"outputTokens": 2,
"totalTokens": 54
},
"request_id": "example-request-id"
}The token counts and request ID are illustrative. Actual values will vary.
API key limitation: An API key is a usage and metering mechanism, not a complete user-authentication system. For a public or user-facing API, configure an appropriate authorizer, such as Amazon Cognito or a suitable Lambda authorizer, where identity-based access is required.
6. Understanding Bedrock Streaming Versus Client Streaming
The implementation uses
converse_stream() to receive model-generated content as events. However, it collects the text fragments in a list and sends one JSON response after generation completes.These are two different behaviors:
| Behavior | Implemented in this example? |
|---|---|
| Bedrock returns model output as stream events | Yes |
| Lambda processes Bedrock events incrementally | Yes |
| API Gateway returns the completed JSON body | Yes |
| Browser receives each generated token immediately | No |
For a conventional JSON API, buffering is often adequate and keeps integration simpler.
For conversational interfaces, live support, or other latency-sensitive applications, true HTTP response streaming can improve time to first byte because the client can start displaying output before the entire generation finishes.
AWS Lambda supports response streaming through Lambda function URLs, the
InvokeWithResponseStream API, and compatible Amazon API Gateway proxy integrations. For Python applications, a custom runtime or the Lambda Web Adapter may be necessary to implement true response streaming.Consult the official Lambda response streaming documentation before changing the integration.
Streaming also has cost and lifecycle implications: the function continues to incur duration charges while producing the response. Select the integration based on measured user experience and operational requirements rather than assuming that streaming is always preferable.
7. Production Hardening Checklist
A working prototype is a starting point, not a production readiness assessment. The following controls should be reviewed before exposing the endpoint to real users.
| Priority | Area | Recommended action | Why it matters |
|---|---|---|---|
| Critical | Lambda timeout | Begin with a 25–28 second timeout for the buffered REST API example and tune after testing. | Prevents the function from running indefinitely and keeps the execution window aligned with upstream limits. |
| Critical | API throttling | Configure API Gateway throttling and appropriate usage controls. | Limits bursts and reduces unexpected consumption. |
| Critical | Input limits | Configure MAX_INPUT_CHARS and enforce request-size limits at the API boundary. | Constrains the amount of text processed per request. |
| Critical | Output limits | Configure MAX_OUTPUT_TOKENS. | Limits generated output and associated inference cost. |
| Critical | Authentication | Configure a suitable authorizer when identity-based access is needed. | API keys alone do not authenticate individual users. |
| High | IAM policy | Restrict the execution role to the approved inference profile and necessary underlying model resources. | Reduces the blast radius of compromised application code. |
| High | Memory allocation | Benchmark 512 MB and 1,024 MB as starting points. | Lambda allocates CPU in proportion to memory, which can affect runtime. |
| High | Budget monitoring | Set AWS Budgets alerts at a threshold appropriate to the workload. | Helps detect unexpected spending. |
| High | Observability | Monitor CloudWatch Logs, duration, failures, throttles, and token usage. | Makes reliability and cost issues visible. |
| High | Model evaluation | Compare Haiku 5.5 with alternatives using representative inputs. | Validates the balance of quality, latency, and price. |
| Recommended | Retry strategy | Use bounded retries and backoff for appropriate transient failures. | Avoids repeated failed calls and uncontrolled latency. |
| Recommended | Data handling | Define prompt retention, log access, and redaction policies. | Reduces the risk of exposing confidential information. |
| Recommended | Deployment | Use AWS SAM, AWS CDK, or CloudFormation. | Makes deployments repeatable and reviewable. |
| Recommended | Automated testing | Test invalid JSON, unauthorized requests, oversized input, throttling, and model failures. | Verifies behavior beyond the successful request path. |
Timeout planning
The Lambda timeout is not the only timeout in the request path. SDK connection and read timeouts, API integration limits, model latency, and client timeouts must all be compatible.
For a buffered REST API, test the full request path and configure timeouts accordingly. If the application needs longer generation or continuous response delivery, assess a supported streaming architecture rather than simply increasing the Lambda timeout.
Regional availability and data residency
Claude Haiku 5.5 supports global cross-Region inference in several Regions, but its regional availability is not identical everywhere.
For example, the current Bedrock model card lists global inference support for Mumbai (
ap-south-1) but does not list in-Region or geography-bound inference there for Haiku 5.5.If an application has a strict requirement that model processing remain within India or another specific geography, do not assume the global inference profile satisfies that requirement. Verify the current regional availability table and select a supported inference option that meets the application's data-residency policy.
The relevant source is the Claude Haiku 5.5 regional availability table .
Model selection
The least expensive model is not necessarily the least expensive solution if it delivers inaccurate results that require retries, human review, or additional processing.
Benchmark the same input set across candidate models. Compare quality, latency, failure rate, output length, and actual token consumption before committing to a production default.
8. Cost Breakdown: Updated for Claude Haiku 5.5
The following estimates use illustrative on-demand US-dollar rates for a small workload. They are not a guaranteed bill and should be recalculated for the selected inference profile and AWS Region.
The current Amazon Bedrock pricing page is the authoritative source for the price that applies to your deployment. The model is billed through AWS Marketplace, as explained in the official Bedrock model card .
Illustrative model pricing
For the calculations below, assume the following global cross-Region inference rates for prompts of up to 100,000 tokens:
| Model | Input price per 1 million tokens | Output price per 1 million tokens |
|---|---|---|
| Claude Haiku 5.5 | $0.10 | $0.50 |
| Claude Haiku 4.5 | $1.00 | $5.00 |
These values are reference rates for cost estimation, not a substitute for verifying the price displayed for your actual Bedrock configuration. Geography-specific inference and other service configurations can have different rates.
Although the listed Haiku 5.5 global per-token prices are 90% lower than those shown for Haiku 4.5, Anthropic reports an average task-running cost reduction of around 75%. The results should not be assumed to match exactly because real applications can consume different token counts and produce different output lengths.
Haiku 5.5 also has tiered long-context pricing. Prompts exceeding 100,000 tokens use higher per-token rates for input, output, and relevant cache operations. This example intentionally uses a much smaller input limit.
Infrastructure pricing assumptions
For the infrastructure calculations, assume:
- 512 MB Lambda memory.
- Three seconds of Lambda duration per request.
- An illustrative Lambda compute price of $0.000016667 per GB-second.
- An illustrative Lambda request price of $0.20 per million requests.
- Amazon API Gateway REST API pricing of $3.50 per million requests in the assumed US Region.
- Global cross-Region inference for Claude Haiku 5.5.
- No other paid features, networking charges, or add-on services.
Regional pricing, account benefits, actual execution duration, logs, data transfer, and other services can change the final bill.
Estimated monthly costs
| Scenario | Requests per month | Haiku 5.5 inference | Lambda estimate | API Gateway estimate | Estimated subtotal |
|---|---|---|---|---|---|
| Hobby / prototype | 500 | $0.065 | $0.013 | $0.002 | Approximately $0.08 |
| Small production | 100,000 | $13.00 | $2.52 | $0.35 | Approximately $15.87 |
The subtotals are calculated before account-specific Free Tier benefits or credits and exclude CloudWatch Logs, data transfer, taxes, and other optional services.
Calculation for the hobby workload
Assume each request consumes approximately 300 input tokens and 200 output tokens.
1
2
3
4
5
Monthly input tokens:
500 × 300 = 150,000
Monthly output tokens:
500 × 200 = 100,000Model inference cost:
1
2
3
4
5
6
7
8
Input:
150,000 / 1,000,000 × $0.10 = $0.015
Output:
100,000 / 1,000,000 × $0.50 = $0.050
Total model inference:
$0.065Estimated Lambda usage:
1
2
3
4
5
6
7
8
9
500 requests × 3 seconds × 0.5 GB
= 750 GB-seconds
750 × $0.000016667
≈ $0.0125
Lambda request charges:
500 / 1,000,000 × $0.20
= $0.0001Estimated API Gateway charge:
1
2
500 / 1,000,000 × $3.50
= $0.00175Total before account-specific credits and other charges:
1
2
3
4
$0.065 + $0.0126 + $0.00175
≈ $0.07935
Estimated total: $0.08 per monthCalculation for 100,000 requests
Using the same token assumptions:
1
2
3
4
5
Input:
100,000 × 300 = 30,000,000 tokens
Output:
100,000 × 200 = 20,000,000 tokensModel inference:
1
2
3
4
5
30,000,000 / 1,000,000 × $0.10 = $3.00
20,000,000 / 1,000,000 × $0.50 = $10.00
Total model inference = $13.00Infrastructure:
1
2
3
4
5
6
7
8
9
10
11
12
13
Lambda execution:
100,000 × 3 seconds × 0.5 GB
= 150,000 GB-seconds
150,000 × $0.000016667 ≈ $2.50
Lambda requests:
100,000 / 1,000,000 × $0.20
= $0.02
Amazon API Gateway:
100,000 / 1,000,000 × $3.50
= $0.35Subtotal:
1
2
3
4
5
Model inference = $13.00
Lambda = $2.52
API Gateway = $0.35
Estimated total = $15.87 per monthThese estimates assume that token usage and execution duration remain stable. Production workloads may have substantially different request sizes, retries, error rates, concurrency patterns, or generated output lengths.
Understanding AWS Free Tier benefits
AWS Free Tier benefits and credits vary according to the account plan, enrollment date, and service eligibility.
AWS announced an updated Free Tier program on July 15, 2025, offering new customers up to $200 in AWS credits and a six-month free plan. Eligibility and credit usage conditions apply.
Read the official AWS Free Tier announcement and verify the benefits shown in your own account before reducing an estimate to zero.
The estimates in this section deliberately exclude those credits so that the underlying workload cost remains visible.
Cost-control recommendations
- Validate every request before invoking the model.
- Limit maximum output tokens and enforce request-size restrictions.
- Use actual token-usage metrics rather than estimating solely from character counts.
- Configure authentication, throttling, and appropriate usage controls.
- Set AWS Budgets alerts and review billing data regularly.
- Benchmark model quality against end-to-end workload cost.
- Recalculate pricing whenever the inference profile, Region, or model configuration changes.
The key point is that model inference can dominate the bill. Selecting the right model and controlling token consumption generally matters more than optimizing a small amount of Lambda execution time.
9. Moving from Prototype to Production
Once the API is working, prioritize improvements that reduce operational risk.
Infrastructure as Code: Deploy the API, execution role, Lambda function, environment variables, and API Gateway configuration using AWS SAM, AWS CDK, or CloudFormation.
Automated testing: Include tests for invalid JSON, unknown tasks, oversized requests, authorization failures, model throttling, and unexpected SDK errors.
Performance monitoring: Track p50, p95, and p99 latency alongside invocation errors, throttling, and token usage.
Security review: Verify that only approved model resources are invokable, secrets are not logged, and the API has appropriate authentication and access controls.
Model governance: Maintain representative test prompts and evaluate quality regressions when updating prompts, SDK versions, or model configurations.
Cost monitoring: Compare estimated and observed spending. Set thresholds based on the expected request volume and cost per request.
A production service should be designed around its measured workload and risk profile, not the number of AWS services in its architecture.
Conclusion
Claude Haiku 5.5, Amazon Bedrock, AWS Lambda, and Amazon API Gateway provide a practical foundation for building serverless AI microservices.
This design keeps application code relatively small, restricts model access through IAM, limits the work accepted per request, and exposes token usage for cost analysis. It can also evolve into a client-streaming architecture when the application needs lower time to first byte.
The objective is not simply to minimize infrastructure cost. It is to balance inference quality, latency, security, reliability, and cost while avoiding operational complexity that the workload does not require.
Discussion
Which model would you choose for this workload: Claude Haiku 5.5, Amazon Nova Micro, or another foundation model?
If you already run a serverless AI API, share your architecture and the biggest challenge you have encountered in production. Comparing implementation details and actual cost measurements is one of the most useful ways to improve these designs.
References
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article