AWS Builder Center

Adding a Cost-Optimized Semantic Layer to a Transactional Data Store with Amazon S3 Vectors and Strands Agents

Add semantic search, recommendations, and RAG to any application backed by a transactional database, using Amazon S3 Vectors as a serverless embedding store alongside the existing system of record. Amazon Bedrock handles embedding and inference, and the open-source Strands Agents SDK orchestrates retrieval without any re-platforming.

Modern applications hold most of their domain data in transactional stores such as articles in a content management system, products in an e-commerce catalog, cases in a support system, accounts in a CRM, claims in a policy administration platform. As generative AI adoption accelerates, these applications are expected to deliver capabilities that go beyond keyword search and manual curation: semantic search that understands intent, automated recommendations, Retrieval Augmented Generation (RAG) for natural-language question answering, and grounded content generation that draws on the existing corpus.
Implementing these capabilities typically requires a new data plane: an embedding pipeline, a vector index, a retrieval API, and an orchestration layer. Many teams default to a dedicated vector database, which introduces a fixed monthly cost floor and an additional operational surface to manage. For workloads where retrieval traffic is variable or unpredictable, the cost and complexity of provisioned vector infrastructure can outweigh the value of the AI features it enables.
In this post, we show how to build a serverless semantic intelligence layer on top of an existing transactional data store using Amazon S3 Vectors , Amazon Bedrock , and the open-source Strands Agents SDK . The pattern is application-agnostic: the same design supports content platforms, product catalogs, support systems, knowledge bases, and any other domain whose system of record is a relational or document database. We also describe when to use Amazon Bedrock Knowledge Bases  instead of building a custom retrieval layer.

Background

Two managed services anchor this architecture.
Amazon S3 Vectors is a purpose-built, serverless vector store integrated into Amazon S3. It supports up to 2 billion vectors per index and up to 10,000 vector indexes per vector bucket, with vector dimensions from 1 to 4,096. Writes are strongly consistent. Newly ingested vectors are immediately queryable. Query latency is sub-second for infrequent queries and as low as 100 milliseconds for more frequent queries. AWS positions S3 Vectors as offering up to 90% cost reduction for vector operations compared with specialized vector databases, with no provisioned infrastructure and a pay-as-you-use pricing model.
Strands Agents is an open-source SDK released by AWS for building autonomous AI agents. It uses a model-first design that treats the foundation model as the core of agent intelligence, integrates natively with Amazon Bedrock and AWS Lambda, and supports the Model Context Protocol (MCP) . In this architecture, Strands Agents orchestrates retrieval and generation tools without requiring teams to hand-code the control flow.

When to use Amazon Bedrock Knowledge Bases instead

Amazon Bedrock Knowledge Bases provides a managed RAG workflow that handles ingestion, chunking, embedding generation, vector storage, synchronization, and retrieval. It supports S3 Vectors as a vector store , which makes it the recommended starting point when:
  • Source documents reside in Amazon S3 or in supported connectors such as Confluence, Salesforce, SharePoint, or web crawls.
  • The built-in chunking strategies (fixed-size, hierarchical, or semantic, among others) meet retrieval quality requirements.
  • The standard Retrieve and RetrieveAndGenerate APIs cover the application's interaction patterns.
Consider the custom architecture in this post when the system of record is a transactional database whose records mutate continuously, when retrieval requires custom logic such as multi-tenant access control filtering or business-rule reranking, or when a single embedding index needs to power multiple capabilities (search, recommendations, RAG, and generation) through a shared API surface.

Solution overview

The architecture has two pipelines that share an embedding index. An ingestion pipeline keeps the index in sync with the system of record. A query pipeline serves search, recommendations, RAG, and grounded generation through a shared retrieval primitive.

Ingestion data flow

The following diagram shows how a record change is propagated to the embedding index.
Data Ingestion Flow
Data Ingestion Flow
The data flows through the ingestion pipeline in the following steps:
  1. A change event from the source application invokes the ingestion AWS Lambda function, which persists or confirms the record in the system of record. The system of record can be Amazon Aurora PostgreSQL, Amazon RDS, Amazon DynamoDB, or Amazon DocumentDB.
  2. The function composes the text fields used for embedding (for example, title, summary, and body) and calls Amazon Bedrock to generate an embedding using a supported model such as Cohere Embed Multilingual v3 (1,024 dimensions).
  3. Amazon Bedrock returns the embedding to the function.
  4. The function calls the S3 Vectors PutVectors API to upsert the embedding, keyed by record ID, with metadata fields (tenant identifier, language, content type, timestamps) for filtering at query time.

Query data flow

The following diagram shows how a user query is served by the four application APIs (/search, /recommendations, /answer, and /generate).
Query data flow
Query data flow
The data flows through the query pipeline in the following steps:
  1. A user query is submitted through Amazon API Gateway with API key or JSON Web Token (JWT) authorization, and is passed to the query AWS Lambda function.
  2. The function calls Amazon Bedrock to embed the query text.
  3. The function calls the S3 Vectors QueryVectors API for similarity search, applying metadata filters (such as tenant identifier or language) to scope the result set, and receives the top-K record IDs ranked by similarity.
  4. The function performs a single batch read from the system of record to hydrate the full records.
  5. For the RAG and generation paths, the function constructs a prompt with the retrieved records as context and calls a foundation model on Amazon Bedrock such as Anthropic Claude Sonnet 4.5. When Amazon Bedrock Guardrails  are configured, content filters and denied-topics policies apply on every invocation.
  6. The function returns the grounded response with inline source citations to the client through Amazon API Gateway.
Cross-cutting controls apply to every step of both pipelines: least-privilege AWS Identity and Access Management (IAM) policies for Amazon Bedrock, S3 Vectors, and the system of record; AWS Key Management Service (AWS KMS) encryption at rest for all data stores; and Embedded Metric Format (EMF) custom metrics published to Amazon CloudWatch.

Why Strands Agents for the orchestration layer

Strands Agents acts as the orchestration layer that selects between retrieval steps at query time. Each capability such as vector search, record hydration, optional query rewriting, optional reranking, is exposed to the agent as a typed tool, and the foundation model decides which tool to invoke based on the user input and the system prompt. The agent loop, retries, and citation formatting are managed by the SDK.
In code, a tool is a regular Python function annotated with the @tool decorator. The SDK derives the parameter schema from type hints and the description from the docstring, and the agent is constructed by passing the model, the tool list, and a system prompt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from strands import Agent, tool
from strands.models import BedrockModel

@tool
def search_records(query: str, top_k: int = 10) -> list[dict]:
"""Find records semantically similar to the query."""
... # embed the query and call S3 Vectors QueryVectors

@tool
def fetch_records(record_ids: list[str]) -> list[dict]:
"""Hydrate full records from the system of record."""
... # batch read from Amazon Aurora

agent = Agent(
model=BedrockModel(model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0"),
tools=[search_records, fetch_records],
system_prompt="Use search_records to find relevant records, "
"fetch_records to hydrate them, and cite every "
"factual claim as [Source: record_id].",
)
This design produces three benefits over a hand-coded retrieval pipeline. First, the procedural code that maps user intent to retrieval steps is removed; the foundation model handles tool selection. Second, new capabilities such as query rewriting, translation, or business-rule reranking are added by registering additional tools, with no changes to the orchestration logic. Third, when Amazon Bedrock Guardrails are configured on the BedrockModel, Strands applies them on every model invocation through the Converse API, providing a single place to enforce content filtering, denied topics, and prompt-attack detection alongside other defense-in-depth controls.
For deployment, Strands provides an official AWS Lambda integration for short-lived requests and supports Amazon Bedrock AgentCore Runtime  for longer-lived sessions that require managed memory, identity, and observability.

Differentiating characteristics of this architecture

Decoupling the vector index from the source of truth is a standard pattern. Customers using PostgreSQL with the pgvector  extension typically follow the same approach, storing embeddings in one table and full records in another. Two characteristics distinguish the architecture in this post.
Workload isolation between the vector index and the transactional store. With pgvector, approximate nearest neighbor (ANN) search runs in the same database engine as transactional traffic and competes for CPU, memory, and I/O. Sizing the cluster for both workloads typically requires overprovisioning. With S3 Vectors, the vector index is a separately managed service. The transactional store is sized for transactions only, the index scales independently with retrieval traffic, and neither workload incurs idle cost on behalf of the other.
A pay-per-use cost shape with no idle floor. Specialized vector databases typically require provisioned capacity. S3 Vectors charges per GB stored and per request (PutVectors, QueryVectors, GetVectors, ListVectors), with no minimum capacity. This is consistent with the cost shape of Amazon Aurora Serverless v2, Amazon DynamoDB on-demand, and AWS Lambda, which makes the architecture suitable for workloads with variable or unpredictable traffic, including multi-tenant SaaS applications where many tenants are active simultaneously but individually low-traffic.
The trade-offs are explicit. Cross-store joins are not supported, so retrieval is a two-hop pattern (index lookup followed by record hydration). At the application level, the index lags the system of record by the duration of the ingestion pipeline (typically seconds), even though writes to S3 Vectors are strongly consistent once they complete. Warm query latency is approximately 100 milliseconds, which is appropriate for search and RAG experiences but not for sub-10-millisecond use cases such as real-time personalization.

Implementation considerations

The following considerations align the architecture with the AWS Well-Architected Generative AI Lens  and the S3 Vectors best practices :
  • Multi-tenancy: Use a separate S3 Vectors index per tenant and enforce isolation through IAM and bucket policies. This pattern scales to the per-bucket index limit and removes the need for runtime tenant filtering on every query.
  • Security: Configure Amazon Bedrock Guardrails with content filters, denied topics, and the prompt-attack filter, and apply them to every LLM invocation. Restrict the agent's tool surface to read-only operations to limit excessive agency. Treat Guardrails as one layer of a defense-in-depth strategy alongside input validation, output review, and least-privilege IAM.
  • Throughput: S3 Vectors supports up to 1,000 combined PutVectors and DeleteVectors requests per second per index (up to 500 vectors per request), with an aggregate ceiling of 2,500 vectors inserted or deleted per second per index. For initial backfills, batch aggressively and consider running ingestion as an AWS Step Functions workflow.
  • Resilience: Use Amazon Bedrock cross-Region inference profiles  to route around regional capacity constraints. Geography-scoped profiles use prefixes such as us., eu., and apac. (for example, us.anthropic.claude-sonnet-4-5-20250929-v1:0), and Bedrock also supports global cross-Region inference profiles (global. prefix) that route across commercial Regions worldwide.
  • Observability: Beyond standard AWS Lambda and Amazon API Gateway metrics, emit EMF custom metrics for embedding latency, retrieval recall@K (sampled against an offline evaluation set), citation-presence rate on RAG responses, and Amazon Bedrock Guardrails block rate.

Cost considerations

For a representative workload of 100,000 records, 100,000 API requests per month, and 50,000 RAG queries per month, using Amazon Aurora Serverless v2 and a small, low-cost foundation model on Amazon Bedrock the bulk of monthly cost concentrates in the transactional database and LLM inference. S3 Vectors, AWS Lambda, and Amazon API Gateway charges typically combine to less than 10% of the total. Validate cost estimates against the AWS Pricing Calculator  using your own region and traffic profile.

Conclusion

For applications whose system of record is a transactional database, S3 Vectors provides a serverless, pay-per-use vector index that scales independently of the source store. Combined with Amazon Bedrock for embedding and inference and the open-source Strands Agents SDK for orchestration, this design adds semantic search, recommendations, RAG, and grounded content generation to an existing application without provisioning a dedicated vector database and without re-platforming the source of truth. For workloads that match the constraints of fully managed RAG, Amazon Bedrock Knowledge Bases with S3 Vectors remains the recommended starting point.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article