We almost blamed FastAPI for a performance issue that had nothing to do with FastAPI. A client reported that one endpoint was “randomly slow.” Same code path, same server, same payload shape, but some requests returned in 90ms and others in 2.5 seconds. At first, the team looked at the framework: maybe async overhead, maybe too many dependencies, maybe Pydantic validation. Wrong direction. The real problem was in PostgreSQL. One query used a filter that looked harmless in code, but under load it triggered a sequential scan because the index did not match the actual access pattern. The endpoint only became slow when the table crossed a certain size, which made it feel like an application bug. What fixed it: 1. Logging the slow query, not just the slow endpoint 2. Running `EXPLAIN ANALYZE` on real production-like data 3. Replacing a generic index with a composite index that matched the query 4. Returning less data from the endpoint instead of “just in case” fields Result: response time dropped from 2.5s to 120ms. My takeaway: when an API gets slow, don’t start by blaming the framework. In many cases, the bottleneck is the database, the query shape, or the amount of data you send back. Have you ever spent hours debugging the app layer and then found the real issue in SQL? #FastAPI #PostgreSQL #Python #BackendDevelopment #APIDesign
Artur Keraz’s Post
More Relevant Posts
-
I spent an hour debugging a query. The values were correct. The timestamps looked right. Nothing crashed. It was still returning wrong results. The change that caused it looked minimal. Before: BETWEEN current_timestamp - interval '25' hours AND from_unixtime(exec_ts/1000) - interval '1' hour After: BETWEEN from_unixtime(prev_ts/1000) AND from_unixtime(exec_ts/1000) - interval '1' hour I ran both functions in the SQL console - they printed the same types. I checked the Trino docs: from_unixtime() returns timestamp(3). Looked fine. But we run in Spark SQL. Different dialect. In Spark, from_unixtime() returns a string. So BETWEEN was comparing a string against a timestamp. No error thrown. Just wrong results. Nothing crashed. Nothing looked obviously broken. That was the whole problem. Useful reminder: when behavior stops making sense, check the real runtime types in the runtime you actually use - not the docs for a different dialect. Shortest path to the bug is often: values → types → coercion rules. That was the moment I remembered {} + [] + {} + [1] JavaScript territory. SQL does the same. Just without the memes.
To view or add a comment, sign in
-
I rebuilt a FastAPI CLI (FApier) to scaffold full projects in <10 seconds. Then I tried to make it production-ready. It worked… until I considered real setups: async DBs, env configs, and multiple integrations in one command. That’s where things got interesting. CLI engine 👉 scaffolds full projects in seconds (no manual setup) Async SQLAlchemy + PostgreSQL 👉 ready for high-concurrency APIs MongoDB (Motor + Beanie) 👉 alternative data layer in 1 command Auto run command 👉 detects env + entry point (0 config) Built-in modules 👉 JWT auth, Redis, WebSockets, background jobs The real challenge was designing a system flexible enough to handle multiple architectures without becoming messy. <10s project generation 0 manual configuration to run multiple stack combinations (SQL + NoSQL + async) and you can test it by running: pip install fapier fapi --help that's it! I broke down the full architecture (and trade-offs) here 👇 https://lnkd.in/e5R4H_dn If you were building this, would you keep everything in one CLI or split generators by use case? #FastAPI #Python #Backend #OpenSource #CLI #DeveloperTools
To view or add a comment, sign in
-
-
DuckDB: The Analytics Swiss Army Knife Most analytics tools make you choose between speed and flexibility. DuckDB gives you both. Here's what makes it different: 🔹 Reads everything CSV, JSON, Parquet, Arrow - file formats Iceberg, Delta Lake - table formats No ETL. No loading. Query directly. 🔹 Columnar engine built for analytics Vectorized execution via SIMD means it processes data in bulk at hardware speed. Not row by row. 🔹 Larger-than-RAM processing Your data doesn't fit in memory? DuckDB spills to disk and keeps going. No cluster needed. 🔹 Runs everywhere Python. R. Java/C++. Node.js. CLI. One duck. Every environment. 🔹 Zero-copy data transfer Works with Arrow natively. No serialization overhead. The best part? It's embedded. No server. No setup. Just import and query. If you're doing local analytics, prototyping pipelines, or exploring large files - DuckDB deserves a spot in your toolkit. #DuckDB #DataEngineering #SQL #Analytics #ApacheSpark #Parquet #DataLake #Python
To view or add a comment, sign in
-
-
🚀 Built my first CRUD API using FastAPI + MySQL and deployed it on Render! 🌐 Live URL: https://lnkd.in/gHKJaCXx Today I created a REST API with full CRUD operations using Python (FastAPI) and MySQL as the database, and deployed it using Render. What I built: ✔ GET → Read data from MySQL ✔ POST → Insert data into MySQL ✔ PUT → Update existing records ✔ DELETE → Remove records from MySQL Deployment: 🌐 Hosted on Render This project helped me understand how backend systems work in real-world applications—from API design to database integration and deployment. Key learnings: - REST API design principles - CRUD operations with MySQL - FastAPI backend development - Deploying applications on Render It’s a simple project, but it reflects real-world backend architecture. Next step: add authentication and improve security. #Python #FastAPI #MySQL #CRUD #BackendDevelopment #Render #Deployment #RESTAPI
To view or add a comment, sign in
-
-
"That's one small step for a man, one giant leap for my backend." 🚀 Today I migrated my Habitual API from SQLite to PostgreSQL. It worked locally - and immediately broke in CI. The technical blocker 🛠️ The heatmap endpoint generates a date range for the last 30 days using a recursive CTE. In SQLite this worked: func.date(func.now(), "-29 days") PostgreSQL doesn't support this modifier syntax. One line, two hours of debugging. I ended up moving the date generation to Python instead of SQL. Cleaner and more portable. The CI struggle 🏗️ Seven commits. Six failures. All named "Little update for CI" - at that point naming stopped mattering (see screenshot 👇). The root cause: my local environment had pinned versions that weren't reflected in requirements.txt. CI pulled newer packages - and everything fell apart. After a few iterations: ✅ 271 tests passed ✅ PostgreSQL running in CI ✅ migrations applied on every push ✅ clean pipeline Next step: Docker and CD. #python #fastapi #postgresql #githubactions #backend
To view or add a comment, sign in
-
-
Most data analysts on my team spent more time writing SQL than actually analysing data. So I built a fix — without touching our existing Superset setup. It's called a Text-to-SQL Sidecar: a standalone FastAPI microservice that sits alongside Apache Superset and turns plain English into validated, safe SQL. You ask: "which products had the highest return rate last quarter?" It generates, validates, and executes the SQL — then hands the results back. A few things I was deliberate about: → AST-level SQL validation (not string matching — trivially bypassable) → Per-database table allowlists so the LLM can only touch what it's supposed to → Schema caching so we're not hammering the DB on every request → LLM-agnostic design — swap the endpoint URL, change the model → Reasoning traces returned alongside SQL so analysts can actually trust the output Superset never needs to know it exists. It just receives SQL. I wrote up the full implementation — architecture, code walkthrough, and the design decisions that make it production-ready. Link in the comments 👇 #DataEngineering #AI #SQL #FastAPI #ApacheSuperset #LLM #Python
To view or add a comment, sign in
-
🌊 VOCÊ USA DATABASE CONNECTION POOL? Você cria conexão a cada request? Pool = reutilizar conexões. 🌊 **Connection Pool:** ```python from sqlalchemy import create_engine from sqlalchemy.pool import QueuePool engine = create_engine( "postgresql://user:pass@localhost/db", poolclass=QueuePool, pool_size=10, max_overflow=20, pool_pre_ping=True ) ``` Benefits: ✅ No connection overhead ✅ Limited connections ✅ Better performance ✅ Resource control Settings: ```python pool_size=10 # Always open max_overflow=20 # Extra when needed pool_timeout=30 # Wait time pool_recycle=3600 # Recycle connections ``` Without pool: ``` Request 1: Connect → Query → Disconnect Request 2: Connect → Query → Disconnect # 100ms overhead per request! ``` With pool: ``` Request 1: Get from pool → Query → Return Request 2: Get from pool → Query → Return # < 1ms! ``` E resultado? 🎯 10x faster 🎯 Less load on DB 🎯 Controlled resources --- Me segue para mais dicas! E aproveita os CUPONS pra joinar a gente: 🔗 https://devopsforlife.io NINJA - 20% OFF: https://lnkd.in/dchtzbWH JEDI - 20% OFF: https://lnkd.in/d9G9R-Ew SUPER SAIYAN - 20% OFF: https://lnkd.in/dtm2Hnj6 --- #devops #database #connectionpool #performance #postgresql #devopsforlife
To view or add a comment, sign in
-
The last two mssql-python releases shipped big features: Bulk Copy in 1.4 for high-throughput data loading, and Apache Arrow in 1.5 for zero-copy analytics. Version 1.6 is about what happens next: you take those features into production, scale up your thread pool, and find out where the driver was quietly holding you back. https://lnkd.in/d-snaHPW
To view or add a comment, sign in
-
A new issue is open in django-modern-rest: https://lnkd.in/dQrvvXzg This one is about improving test performance in dmr_rf and dmr_client. The idea is to optimize the JSON encoding path used in tests, since json.dumps is slower and the project may be able to reuse a faster approach already used elsewhere. Why it matters: this is a practical performance task in a real Python/Django codebase. If you want to take it: - check the issue thread first - make sure it is still unassigned - ask in the issue if you can take it - get maintainer confirmation - then start At Kanzu, we’ll occasionally share selected contribution opportunities around real Python work.
To view or add a comment, sign in
-
🗄️ You can’t build RAG without storing vectors somewhere. Choose badly now… pay for it later. Day 8 of building Brio — I evaluated vector database options and chose PGVector via Neon. What I considered: → Pinecone — polished managed experience, but another service + extra cost → Weaviate / Qdrant — powerful, but more infra to manage → PGVector on Postgres — familiar, flexible, fewer moving parts I chose Neon + PGVector. Why: → It’s Postgres (already know how to operate it) → Vector similarity search built in → Serverless scaling with Neon → Works cleanly with Spring AI VectorStore → SQL + vectors together = easier metadata filtering Big lesson: The best engineering choice is rarely the most exciting one. It’s the one you can ship, debug, and maintain without 2am drama. For an early-stage RAG product: Would you choose a dedicated vector DB… or Postgres + PGVector? #RAG #SpringAI #Java #AIEngineering #VectorDB #Pgvector #postgres
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
looks like you don't use monitoring tools