Good to see you again. You now have a provider-neutral architecture: React communicates with FastAPI; FastAPI owns access to PostgreSQL/pgvector, file storage, and model services. This lesson makes that diagram operational by choosing a free-tier development and demo stack deliberately rather than collecting random free accounts.
By the end, you will have a short decision record naming a primary service, its hard limits, an application-level budget, and a fallback for each dependency. The goal is not to claim that a free tier can safely run a real customer-support business. It is to build a reliable portfolio demo while being able to explain its constraints honestly in an interview.
Treat “free” as a set of constraints
A free plan can be excellent for learning, but “$0” is not a technical requirement. For each architectural boundary, evaluate five things:
| Criterion | Question to answer | Why it matters here |
|---|---|---|
| Capability | Does it actually support the needed feature? | PostgreSQL must support pgvector; a model service must cover text generation and, eventually, embeddings. |
| Hard limits | What are the storage, request, compute, file-size, or rate limits? | Limits determine the safe size of your demo corpus and traffic. |
| Operational behavior | Does the service pause, scale to zero, expire, or lack backups? | A portfolio demo that fails after inactivity is still a failure mode you must plan for. |
| Data boundary | What data leaves your machine or is retained by the provider? | Support documents and conversations may contain sensitive material. |
| Fallback | What happens when the limit is reached or a provider is unavailable? | Your application should fail predictably rather than expose an internal error. |
A useful rule is:
A provider is not selected until you can state its limit, the application guardrail below that limit, and the fallback when the guardrail is crossed.
Keep two categories separate in your notes:
- Provider facts: published limits such as of database storage.
- Your engineering policy: a stricter cap you impose, such as using no more than in a demo database.
The provider controls the first. You control the second.
Choose a hosted PostgreSQL and vector-search baseline
For the hosted database, select Neon Free as the capstone’s primary demo database, with local PostgreSQL plus pgvector in Docker as the development and outage fallback.
This is a focused decision: Neon provides PostgreSQL, its extensions library includes pgvector, and its free plan publishes both a storage limit and a compute budget. It does not eliminate the need for local development; rather, it gives you a realistic hosted database endpoint for a deployed demonstration.
Read Neon’s pricing information to identify the difference between stored database data and active database compute. This distinction is especially important for a RAG application, where embedding storage and retrieval queries affect different limits.
On the Neon pricing plans section, read the Free-plan allocation from the free plan figures. Note the published project count, 100 monthly CU-hours per project, and 0.5\text{ GB} storage per project. Then find the section describing Neon's Postgres extensions library and confirm extension support; pgvector capability is a prerequisite, not a bonus. Finally, in Your questions, answered, locate the explanation beginning “A CU ...” and read the usage explanation. Focus on why an idle database consumes no compute allocation, but an actively queried one does.
Read the compute budget correctly
A Compute Unit represents database compute capacity. A CU-hour measures how much active compute your database uses over time. A rough planning formula is:
At an average of CU, the CU-hour allowance corresponds roughly to:
active compute hours per day over a thirty-day month. This is not a promise that your database will run exactly that long: load, query patterns, and autoscaling affect usage. It is a useful warning that a continuously busy public service is not the intended use case for this plan.
For a portfolio application with intermittent testing, manual demos, and a small evaluation set, the model is reasonable. For an always-on public product receiving steady traffic, you would expect to outgrow it.
Database storage is not just document text
The database limit includes relational records, chunk text, vector values, metadata, indexes, and database overhead. Original PDFs should remain in object storage, as your architecture established in the previous lesson.
For a vector with dimensions, the raw numeric vector alone is approximately:
For example, vectors of dimensions require about:
bytes, or roughly , before chunk text, metadata, indexes, and other tables. The true database footprint will be larger.
Therefore, set an intentionally conservative cap for the first demo:
- Use a small, representative knowledge base.
- Target no more than 1,000 indexed chunks initially.
- Treat of database use as your internal warning threshold, leaving room for indexes, conversations, tickets, and later iteration.
- Record database usage after every substantial ingestion run.
This is an engineering budget, not a Neon requirement. The purpose is to discover growth early rather than discovering it when the provider rejects a write.
Database decision
| Decision field | Choice |
|---|---|
| Primary hosted database | Neon Free PostgreSQL with pgvector |
| Published constraints | storage and CU-hours per project per month |
| Internal demo budget | Small corpus; initially at most 1,000 chunks; investigate usage at or CU-hours |
| Fallback | Local PostgreSQL with pgvector through Docker Compose |
| Fallback trigger | Hosted quota exhaustion, provider outage, failed provisioning, or local/offline development |
| Interview trade-off | Good for a small intermittent demo; insufficient evidence to claim it supports sustained production traffic |
The key architectural choice is to use a normal PostgreSQL connection string in configuration. Your FastAPI code should not be structured around Neon-specific business logic. That preserves the option to run the same migrations and queries against local PostgreSQL.
Select object storage, but plan for inactivity
For original knowledge-source files, select Supabase Storage Free for the hosted demo. It is a distinct service from the Neon database choice: FastAPI writes original document bytes to object storage, while PostgreSQL stores only source metadata and an object key.
Read Supabase’s Free-plan limits with the narrow goal of assessing hosted object storage for uploaded support documents. Pay attention to the storage allowance, file-upload cap, egress, and project-pausing behavior.
On Supabase’s Free plan, first note the inactivity constraint. This affects demo reliability after a period without use. Then, in the Storage table within the same Free-plan section, read the storage allowance. Record the 1\text{ GB} storage allowance, 5\text{ GB} cached egress allowance, and 50\text{ MB} maximum upload size. Do not confuse the provider’s maximum file size with the smaller cap your application should enforce.
The published maximum upload size is an upper boundary, not a sensible default for a first RAG demo. Large PDFs take longer to upload, parse, chunk, embed, and index. They also make failure recovery harder.
Set this application policy:
- Accept only the file types your first ingestion pipeline will support.
- Enforce a application upload limit, even though the host permits .
- Keep the hosted demo corpus below of original files.
- Preserve the original, non-sensitive demo documents in a local backup location so that the hosted bucket can be recreated.
- Before giving a portfolio demonstration, open the application after any long idle period and verify the provider project has resumed.
The “non-sensitive” qualifier matters. Do not use real customer support exports, credentials, or confidential company documents just because a free storage bucket is convenient. Create or use sanitized sample documentation for the capstone.
Storage decision
| Decision field | Choice |
|---|---|
| Primary hosted file storage | Supabase Storage Free |
| Published constraints | storage, cached egress, maximum upload, project pause after one inactive week |
| Internal demo budget | per upload and less than total source-file storage |
| Fallback | A mounted local filesystem directory during development, plus local copies of the sanitized demo corpus |
| Fallback trigger | Storage allocation pressure, an inactive paused project, provider outage, or local development |
| Interview trade-off | Suitable for a bounded document demo; not a substitute for a backup, retention, or disaster-recovery strategy |
Store a provider-neutral object key in PostgreSQL, such as organizations/acme/sources/<source-id>/original.pdf, rather than treating a public provider URL as the source of truth. This makes a future storage move a configuration and migration task rather than a rewrite of your domain model.
Make the model-provider choice reversible
The model service is the least stable free-tier dependency. Models are added, removed, rate-limited, and repriced more frequently than PostgreSQL or object storage. So the correct decision is not “find the best free model forever.” It is to choose a provider strategy that keeps the model replaceable.
A model gateway can simplify experimentation because one API format can address multiple models. The following short video illustrates that idea and how free models may be discovered in a provider catalog. Treat it as a workflow overview, not as a durable quota contract.
How to Use AI Models API for Free | OpenRouter Tutorial
Watch “How to Use AI Models API for Free” by The Coding Koala to understand the gateway pattern: one API integration with a configurable model identifier. This is useful for experimentation, but you should always verify current limits in the provider’s own dashboard and documentation before relying on a model.
Watch the gateway overview. Focus on the distinction between a common endpoint and the selected model identifier, plus the use of a free-model filter. Notice what the video does not establish: a guaranteed request rate, token allowance, availability commitment, or long-term model catalog.
For this capstone, choose the following approach:
- Use a hosted free model endpoint through a gateway such as OpenRouter for low-volume development experiments and model comparisons.
- Record the exact model identifier, published context limit, rate limit, and any daily quota at the time you configure it.
- Do not promise that a free hosted endpoint will power continuous public use of the demo.
- Configure a local Ollama runtime as the development fallback for generation and, where supported by the selected local model, embeddings.

The local option has no provider request quota, but it has a different budget: your laptop’s RAM, CPU or GPU capacity, disk space, latency, and model quality. It is not automatically “free” in the operational sense, and it is not automatically secure merely because it runs locally. Still, it is a valuable fallback because it lets you keep building when a hosted free endpoint is unavailable.
For a RAG application, also avoid a common mistake: generation and embeddings are separate capabilities. A model that writes an answer may not supply embeddings. Before selecting a model configuration, verify that you have a working plan for both:
| Capability | What to verify before using it |
|---|---|
| Text generation | Context-window size, request-rate limits, output limit, structured-output support if needed, and current availability |
| Embeddings | Embedding support, vector dimension, batch limits, rate limits, and whether the model is available through the same provider |
| Local fallback | RAM/disk requirements, observed latency on your machine, and whether your local configuration supports the needed capability |
Your application-level guardrail should be modest: one user request should result in at most one retrieval embedding call and one generation call under normal conditions. Later lessons will add retries and rate-limit handling; for now, the important decision is not to hide provider calls throughout route handlers.
Model-service decision
| Decision field | Choice |
|---|---|
| Primary development model path | A currently available free hosted model through a configurable gateway |
| Published quota status | Must be checked and recorded when the model is selected; do not infer guarantees from a “free” catalog label |
| Internal demo policy | Low-volume manual testing, small evaluation set, no claim of continuous public availability |
| Fallback | Local Ollama with tested generation and embedding configurations where applicable |
| Fallback trigger | Hosted model rate limit, quota exhaustion, provider error, removed model, or privacy-sensitive local testing |
| Architecture requirement | FastAPI is the only caller; provider and model identifiers come from server configuration, never the React client |
Write the capstone service decision record
Create docs/service-decisions.md in the repository you will build next. This is a lightweight architecture decision record, not bureaucracy. It gives you an artifact to revisit when a quota changes and evidence for explaining your choices in interviews.
Use this structure:
# Free-tier service decisions
## Scope
This configuration supports a small, sanitized portfolio demo.
It is not presented as a production SLA or compliance-ready deployment.
## PostgreSQL and vector search
Primary: Neon Free PostgreSQL with pgvector
Published limits: 0.5 GB storage; 100 CU-hours per project per month
Application budget: 1,000 indexed chunks initially; investigate at 250 MB or 80 CU-hours
Fallback: local PostgreSQL plus pgvector in Docker Compose
Trigger: quota pressure, outage, failed provisioning, or offline development
## Object storage
Primary: Supabase Storage Free
Published limits: 1 GB storage; 5 GB cached egress; 50 MB maximum upload
Application budget: 10 MB per upload; less than 250 MB total source files
Fallback: local mounted file storage and a local copy of the sanitized demo corpus
Trigger: inactive paused project, allocation pressure, provider failure, or local development
## Model services
Primary: selected hosted free model through a configurable gateway
Record before implementation: model ID, generation limits, embedding limits,
context window, rate limit, date checked
Fallback: local Ollama configuration tested on this machine
Trigger: rate limit, quota exhaustion, model removal, provider error, or local-only work
## Explicit non-goals
No production traffic guarantee
No storage-backup guarantee
No real customer documents in the demo corpus
Then perform a small provisioning check before writing application code:
- Create the hosted database and verify that pgvector can be enabled.
- Create the storage project and upload one sanitized sample document smaller than .
- Make one successful text-generation request through the selected hosted model path.
- Verify the local model fallback can run on your machine.
- Record the date and observed constraints in the decision document.
This check prevents a familiar AI-assisted-development failure mode: designing against an assumed service capability, then discovering only during implementation that the plan, region, extension, or model access differs from what you expected.
Key takeaways
A free-tier stack is a collection of bounded dependencies, not a production deployment plan. For this capstone:
- Neon Free is the hosted PostgreSQL and pgvector choice, with storage and CU-hours as the main constraints.
- Supabase Storage Free holds original demo documents, with storage, a provider upload maximum, and an inactivity-pause risk.
- A configurable hosted free model path supports low-volume experimentation, while local Ollama provides a practical fallback when hosted quotas or availability fail.
- Your stricter application budgets, local fallbacks, and written decision record are what turn provider limits into an engineering plan.
Next, you will create the monorepo that gives these decisions a home: separate React frontend, FastAPI backend, and infrastructure configuration, with clear boundaries from the first commit.
Can't find a good explanation? Sign up and we'll make it for you
Sign up