Module 1 — Thinking Like a Backend Engineer
Lesson 1 — What Makes Backend Engineering Advanced?
আপনি একটি free preview lesson দেখছেন।
একটি backend application বানানো তুলনামূলকভাবে সহজ।
কিন্তু এমন একটি backend system বানানো, যা traffic বাড়লেও, dependency fail করলেও, একই data নিয়ে concurrent operation হলেও, requirement বদলালেও, এবং বহু engineer একসাথে কাজ করলেও নির্ভরযোগ্য থাকে — সেটাই কঠিন।
এই জায়গা থেকেই Advanced Backend Engineering শুরু হয়।
Advanced Backend Engineering মানে শুধু আরও বেশি framework, library বা infrastructure tool জানা নয়।
মূল বিষয় হলো:
একটি system কীভাবে behave করবে, কোথায় fail করতে পারে, কীভাবে evolve করবে, এবং কোন trade-off গ্রহণযোগ্য — তা বুঝে design করা।
এই Lesson শেষে আপনি যা বুঝবেন
এই lesson শেষে আপনি বুঝতে পারবেন:
- সাধারণ backend development এবং advanced backend engineering-এর পার্থক্য;
- কেন working code মানেই correct system নয়;
- scale কীভাবে নতুন সমস্যা তৈরি করে;
- failure কেন production system-এর normal অংশ;
- concurrency কীভাবে seemingly-correct code ভেঙে দিতে পারে;
- system evolve করার সময় কেন compatibility গুরুত্বপূর্ণ;
- team structure কীভাবে architecture-এ প্রভাব ফেলে;
- কেন architecture মূলত trade-off management।
1. Feature বানানো আর System Engineer করা এক জিনিস নয়
ধরি requirement খুব সাধারণ:
একজন customer একটি order তৈরি করতে পারবে।
একটি basic implementation হতে পারে:
Client
│
▼
OrderController
│
▼
OrderService
│
▼
OrderRepository
│
▼
PostgreSQL
Request:
POST /orders
Application request validate করল, order তৈরি করল, database-এ save করল, তারপর response দিল।
Feature কাজ করছে।
কিন্তু production-এ কিছু প্রশ্ন চলে আসে:
- একই request দুইবার এলে কী হবে?
- order তৈরি হয়ে গেলে, কিন্তু client response না পেলে কী হবে?
- client retry করলে duplicate order হবে কি?
- দুইজন customer একই সময়ে শেষ item কিনতে চাইলে কী হবে?
- database slow হলে কী হবে?
- payment succeed করল কিন্তু inventory fail করলে কী হবে?
- traffic 100 RPS থেকে 10,000 RPS হলে কী হবে?
- system unhealthy হলে আমরা জানব কীভাবে?
- database schema change করলে পুরোনো application instance break করবে কি?
এগুলো controller বা annotation-এর প্রশ্ন নয়।
এগুলো system engineering-এর প্রশ্ন।
2. Working Code মানেই Correct System নয়
ধরি আমাদের endpoint:
POST /orders
Request:
{
"productId": "P123",
"quantity": 1
}
Server একটি order তৈরি করল:
{
"orderId": "O456",
"status": "CREATED"
}
এখন sequenceটা এমন হলো:
Client
│
│ POST /orders
▼
Server
│
├── Order তৈরি হলো
│
├── Response পাঠানো হলো
│
X Network connection lost
Server-এর perspective থেকে operation সফল।
কিন্তু client response পায়নি।
Client জানে না:
Order তৈরি হয়েছে?
নাকি request fail করেছে?
তাই client retry করল।
POST /orders
Server আবার নতুন order তৈরি করতে পারে।
এখন দুইটি request-ই technically successful।
কিন্তু business result ভুল:
Expected order = 1
Actual order = 2
এখান থেকে একটি গুরুত্বপূর্ণ principle পাই:
Request-level correctness আর business-level correctness এক জিনিস নয়।
পরে আমরা idempotency দিয়ে এই ধরনের সমস্যা কীভাবে solve করতে হয় তা শিখব।
এই lesson-এ লক্ষ্য শুধু problem চিনতে শেখা।
3. Scale Complexity তৈরি করে
ধরি প্রথমে application receive করছে:
10 requests/second
Architecture:
Client
│
▼
Application
│
▼
PostgreSQL
এটা সহজেই কাজ করতে পারে।
এরপর traffic হলো:
1,000 requests/second
তারপর:
10,000 requests/second
এখন আগে যেসব বিষয় গুরুত্বহীন মনে হতো, সেগুলো problem হয়ে দাঁড়াতে পারে।
যেমন:
- slow SQL query;
- missing index;
- বেশি database connection;
- unnecessary network call;
- CPU-heavy processing;
- synchronous operation;
- large response;
- memory pressure;
- hot database row।
একটি common solution হতে পারে application instance বাড়ানো:
Load Balancer
│
┌─────────────┼─────────────┐
▼ ▼ ▼
API #1 API #2 API #3
│ │ │
└─────────────┼─────────────┘
▼
PostgreSQL
Application layer scale করল।
কিন্তু এখন তিনটি instance একসাথে database-এ বেশি connection খুলছে।
Result:
Application bottleneck কমলো
কিন্তু
Database bottleneck তৈরি হলো
এখানে মূল lesson হলো:
একটি component scale করলেই পুরো system scale হয় না।
System-কে end-to-end বুঝতে হয়।
4. Failure Production System-এর স্বাভাবিক অংশ
Production system-এ failure exception নয়।
Failure expected।
উদাহরণ:
- network timeout;
- database slow;
- application restart;
- container terminate;
- DNS failure;
- external API unavailable;
- message duplicate delivery;
- connection reset।
ধরি flow:
Order Service
│
▼
Payment Service
│
▼
Inventory Service
Payment succeed করেছে।
Inventory fail করেছে।
এখন কী হবে?
Possible options:
Payment refund করা
Inventory retry করা
Order pending রাখা
Order cancel করা
Manual review-এ পাঠানো
কোনটা correct?
একটা universal answer নেই।
Business context-এর উপর depend করবে।
এই জন্য:
Failure handling architecture-এর অংশ।
Failure handling পরে add করা optional feature নয়।
5. Concurrency Correct Code-ও ভেঙে দিতে পারে
ধরি inventory table:
product_id | available_quantity
-----------|-------------------
P123 | 1
একটি item বাকি।
দুইজন customer একই সময়ে কিনতে চাইল।
Request A read করল:
available_quantity = 1
Request B-ও read করল:
available_quantity = 1
দুইজনই মনে করল item available।
Code:
if (product.getAvailableQuantity() > 0) {
product.decreaseQuantity();
repository.save(product);
}
Single request দিয়ে দেখলে code ঠিক।
কিন্তু দুইটি request parallel run করলে সমস্যা হতে পারে।
এটাই concurrency-এর challenge।
Sequentially correct code concurrently incorrect হতে পারে।
পরে আমরা শিখব:
- transactions;
- isolation levels;
- optimistic locking;
- pessimistic locking।
এখন শুধু problemটা চিনে রাখুন।
6. Backend System মূলত State নিয়ে কাজ করে
Backend system সাধারণত state manage করে।
যেমন:
- order;
- payment;
- inventory;
- account balance;
- subscription;
- identity;
- permissions।
এই state ভুল হলে system outwardly healthy দেখালেও business broken হতে পারে।
উদাহরণ:
Expected balance = €100
Actual balance = €150
Server চলছে।
CPU normal।
API 200 OK দিচ্ছে।
তবুও system incorrect।
তাই backend engineer-এর responsibility শুধু:
"API চলছে কি?"
না।
বরং:
"System-এর state correct আছে কি?"
এটাই বড় প্রশ্ন।
7. Time-এর সাথে System আরও Complex হয়
Production system static নয়।
System evolve করে।
ধরি প্রথম version API return করে:
{
"id": "123",
"name": "Laptop"
}
নতুন requirement অনুযায়ী আমরা চাই:
{
"id": "123",
"displayName": "Laptop"
}
Simple rename মনে হচ্ছে।
কিন্তু problem:
- অন্য service এখনো
nameexpect করছে; - mobile app-এর পুরোনো version
nameexpect করছে; - Kafka-তে পুরোনো event আছে;
- background worker old schema use করছে।
এই কারণে production system-এ গুরুত্বপূর্ণ হয়ে যায়:
Backward compatibility
Schema evolution
Migration
Deprecation
Rollback
Deployment order
Architecture শুধু final state design নয়।
Architecture হলো:
আজকের system থেকে আগামী দিনের system-এ safely যাওয়া।
8. Team বড় হলে Architecture-এর গুরুত্ব বাড়ে
একজন engineer পুরো application maintain করলে coordination সহজ।
কিন্তু ধরুন organisation-এ আছে:
Accounts Team
Catalog Team
Orders Team
Payments Team
Inventory Team
Shipping Team
এখন Orders team যদি event format change করে:
Orders change
↓
Inventory break
Payments API change করলে:
Payments change
↓
Checkout break
যদি সবাই সবার database directly access করে, ownership unclear হয়ে যায়।
Architecture এখানে সাহায্য করে define করতে:
- কে কোন system-এর owner;
- কোন data কে manage করবে;
- কোন interface stable;
- কোথায় dependency allowed;
- কোন team independently deploy করতে পারবে।
তাই architecture শুধু software নিয়ে নয়।
Architecture organisational structure-এর সাথেও সম্পর্কিত।
9. Advanced Engineer Technology দিয়ে শুরু করে না
Common question:
কোন database সবচেয়ে ভালো?
Better question:
এই workload-এর requirement কী?
Database choose করার আগে প্রশ্ন করা উচিত:
Transaction দরকার কি?
Durability কতটা গুরুত্বপূর্ণ?
Access pattern কেমন?
কত data হবে?
Read বেশি নাকি write বেশি?
Stale data acceptable কি?
Latency target কত?
Operational complexity কতটা গ্রহণযোগ্য?
একইভাবে:
Kafka
Redis
Microservices
Kubernetes
Temporal
NoSQL
এসব দিয়ে শুরু করা উচিত নয়।
প্রথমে requirement।
তারপর technology।
Technology should follow requirements.
10. প্রতিটি Solution নতুন Problem আনে
ধরি database read slow।
আমরা Redis add করলাম।
Before:
Application
│
▼
PostgreSQL
After:
Application
│
▼
Redis
│
Cache miss
▼
PostgreSQL
Latency improve করল।
কিন্তু এখন নতুন problem:
PostgreSQL-এ:
Price = €100
Redis-এ:
Price = €90
তাহলে কোনটা correct?
আমরা solve করেছি:
Performance
কিন্তু introduce করেছি:
Consistency problem
এটাই advanced backend engineering-এর recurring pattern:
একটি problem solve করলে প্রায়ই নতুন trade-off তৈরি হয়।
11. Microservices সবসময় Better নয়
Microservices কিছু advantage দিতে পারে:
- independent deployment;
- team ownership;
- separate scaling;
- domain separation।
কিন্তু এর cost:
- network failure;
- distributed transactions;
- operational overhead;
- observability complexity;
- deployment complexity;
- cross-service debugging।
তাই:
Microservices ব্যবহার করলেই architecture advanced হয়ে যায় না।
অনেক ক্ষেত্রে modular monolith-ই better engineering decision।
Advanced engineering মানে complex solution choose করা নয়।
Appropriate solution choose করা।
12. Architecture মানে Trade-Off Management
একজন engineer বলল:
Kafka use করি, কারণ Kafka scalable।
এটা weak reasoning।
Better reasoning:
আমাদের durable event retention, replay, partition-level ordering এবং multiple independent consumer দরকার। Kafka এই requirementগুলো satisfy করে, তবে এর সাথে infrastructure এবং operational complexity বাড়বে।
এখানে দুই দিকই আছে:
Benefit
+
Cost
এটাই architectural thinking।
Question হওয়া উচিত না:
Kafka ভালো কি?
বরং:
Kafka কোন problem solve করছে এবং এর বিনিময়ে আমরা কী complexity নিচ্ছি?
13. Production-এ "Done" এর Definition বদলে যায়
Simple application-এ:
✓ Code works
✓ Test passes
✓ API responds
Production system-এ:
✓ Functional requirement works
✓ Concurrent operation safe
✓ Retry safe
✓ Failure behavior defined
✓ Useful logging আছে
✓ Metrics আছে
✓ Deployment safe
✓ Rollback possible
✓ Database migration compatible
✓ Capacity understood
এই জন্য production readiness শুধু code-এর property নয়।
এটা পুরো system-এর property।
14. Backend Engineer-এর Mental Checklist
এই course জুড়ে আমরা বারবার কিছু প্রশ্ন করব।
Correctness
এই operation invalid business state তৈরি করতে পারে কি?
Failure
Dependency fail করলে কী হবে?
Concurrency
একই operation একসাথে run করলে কী হবে?
Scale
Traffic 100× হলে কী হবে?
Data
Source of truth কোথায়?
Consistency
Data কতটা stale হতে পারে?
Recovery
Partial failure থেকে system recover করতে পারবে?
Observability
System broken হলে আমরা জানব কীভাবে?
Evolution
এই change পুরোনো consumer break করবে কি?
Operations
Incident হলে অন্য engineer বুঝতে পারবে কী ঘটছে?
এই প্রশ্নগুলো advanced backend engineer-এর core habit।
Practical Exercise — Simple Order System
Architecture:
Client
│
▼
Order API
│
▼
PostgreSQL
Endpoint:
POST /orders
Request:
{
"productId": "P123",
"quantity": 1
}
Application:
1. Inventory check করে
2. Order তৈরি করে
3. Inventory কমায়
4. Order return করে
Current traffic:
100 requests/second
এখন নিচের scenarioগুলো analyse করুন।
Scenario 1 — Concurrent Purchase
দুইজন customer একই সময়ে শেষ item কিনতে চায়।
ভাবুন:
কী ভুল হতে পারে?
Solution এখন দরকার নেই।
Problem identify করুন।
Scenario 2 — Client Retry
Order successfully তৈরি হয়েছে।
কিন্তু response client-এর কাছে পৌঁছেনি।
Client retry করল।
প্রশ্ন:
কী ধরনের incorrect business state তৈরি হতে পারে?
Scenario 3 — Slow Database
Normally query latency:
20 ms
হঠাৎ হলো:
5 seconds
ভাবুন:
- request-এর কী হবে?
- application resource-এর কী হবে?
- user experience কীভাবে affect হবে?
Scenario 4 — Traffic Spike
Traffic:
100 RPS
থেকে:
10,000 RPS
হলো।
কোন কোন component bottleneck হতে পারে?
Technology solution না দিয়ে আগে problem identify করুন।
Scenario 5 — Redis যোগ করা হলো
Database load কমানোর জন্য Redis add করা হলো।
এখন ভাবুন:
কী ধরনের নতুন consistency problem আসতে পারে?
Exercise Format
প্রতিটি scenario-এর জন্য তিনটি প্রশ্নের উত্তর দিন:
1. কী fail করতে পারে?
2. Business impact কী হতে পারে?
3. Solution choose করার আগে কী information দরকার?
এই exercise-এর উদ্দেশ্য technology select করা নয়।
উদ্দেশ্য:
Solution-এর আগে problem বুঝতে শেখা।
Key Takeaways
এই lesson থেকে সবচেয়ে গুরুত্বপূর্ণ বিষয়গুলো:
1. Working code যথেষ্ট নয়
System-কে failure, retry, concurrency এবং change-এর মধ্যেও correct থাকতে হবে।
2. Scale assumption বদলে দেয়
100 RPS-এ যে architecture কাজ করে, 100,000 RPS-এ সেটি কাজ নাও করতে পারে।
3. Failure normal
Production system design করতে হবে failure ধরে নিয়ে।
4. Concurrency dangerous
Sequentially correct code parallel execution-এ incorrect হতে পারে।
5. System evolve করে
Backward compatibility এবং migration খুব গুরুত্বপূর্ণ।
6. Architecture team structure-এর সাথেও সম্পর্কিত
Ownership এবং dependency design-এর অংশ।
7. প্রতিটি solution-এর cost আছে
Redis, Kafka, microservices — সবকিছু problem solve করে, আবার নতুন complexity আনে।
8. Architecture মানে trade-off
সঠিক প্রশ্ন:
কোন technology সবচেয়ে ভালো?
না।
সঠিক প্রশ্ন:
আমাদের requirement-এর জন্য কোন trade-off সবচেয়ে গ্রহণযোগ্য?
Next Lesson
Lesson 2 — Understanding the Request Lifecycle
পরের lesson-এ আমরা একটি request-এর পুরো journey দেখব:
Client
↓
Load Balancer
↓
Application
↓
Cache
↓
Database
↓
External Dependencies
আমরা বুঝব:
- latency কোথায় তৈরি হয়;
- কোন layer-এ failure হতে পারে;
- কোন resource কোথায় consume হয়;
- এবং backend optimize করার আগে complete request lifecycle বোঝা কেন জরুরি।