Cache-Control একটি HTTP হেডার যা নির্দেশাবলীর একটি সেটের মাধ্যমে ক্লায়েন্ট, প্রক্সি সার্ভার এবং CDN-এ রিসোর্সের ক্যাশিং নিয়ম সংজ্ঞায়িত করে। পুরানো Expires হেডারের বিপরীতে, Cache-Control ডজন ডজন কম্বিনেশন সমর্থন করে: max-age সেকেন্ডে জীবনকাল নির্ধারণ করে, private এবং public ক্যাশ প্রাপ্যতা নিয়ন্ত্রণ করে, no-cache এবং no-store — বাধ্যতামূলক যাচাইকরণ। Google Web Dev (2025) অনুসারে, সঠিক Cache-Control কনফিগারেশন বারবার ভিজিটের জন্য পৃষ্ঠা লোডের সময় 50-80% কমাতে পারে। এটি হেডারকে ওয়েব এবং মোবাইল অ্যাপ্লিকেশন কর্মক্ষমতার জন্য গুরুত্বপূর্ণ করে তোলে।
মূল বিষয়
Cache-Control একটি HTTP হেডার, যা HTTP/1.1 (RFC 7234)-এ প্রমিত, যা সার্ভারকে নির্দিষ্ট করতে দেয় যে ক্লায়েন্ট, প্রক্সি এবং CDN কতক্ষণ এবং কীভাবে প্রতিক্রিয়া ক্যাশ করতে পারে। Expires (HTTP/1.0) এর বিপরীতে, Cache-Control নির্দেশাবলী ব্যবহার করে — কমা দ্বারা যুক্ত টেক্সট কমান্ড: Cache-Control: public, max-age=3600, must-revalidate। হেডার ক্যাশিং চেইনের প্রতিটি লিঙ্কের উপর সূক্ষ্ম নিয়ন্ত্রণ প্রদান করে।
ক্যাশিং ওয়েব এবং মোবাইল অ্যাপ্লিকেশন কর্মক্ষমতার মৌলিক প্রক্রিয়াগুলির মধ্যে একটি। এটি ছাড়া, প্রতিটি ব্যবহারকারীর অনুরোধ সরাসরি সার্ভারে যাবে, যা অতিরিক্ত লোড এবং বিলম্বের কারণ হবে। Cache-Control তিনটি ক্যাশিং স্তর সংজ্ঞায়িত করে: ব্রাউজার/অ্যাপ্লিকেশন (প্রাইভেট ক্যাশ), প্রক্সি সার্ভার (শেয়ার্ড ক্যাশ), এবং CDN (ডিস্ট্রিবিউটেড ক্যাশ)। প্রতিটি স্তর নির্দেশাবলী ভিন্নভাবে ব্যাখ্যা করে।
ভুল Cache-Control কনফিগারেশন কর্মক্ষমতা সমস্যার সবচেয়ে সাধারণ কারণগুলির মধ্যে একটি। অত্যধিক আক্রমণাত্মক ক্যাশিং ব্যবহারকারীদের পুরানো ডেটা দেখায়। খুব দুর্বল ক্যাশিং সার্ভারে অতিরিক্ত অনুরোধ এবং ধীর লোডিংয়ের দিকে নিয়ে যায়। Akamai (2025) অনুসারে, স্ট্যাটিক কন্টেন্টের জন্য Cache-Control অপ্টিমাইজ করলে সার্ভার লোড 70-90% কমে যায় এবং মোবাইল ব্যবহারকারীদের জন্য লোডের সময় 40-60% উন্নতি হয়।
Cache-Control HTTP/1.1 (RFC 2616, 1999)-এ Expires-এর প্রতিস্থাপন হিসেবে আবির্ভূত হয়। Expires-এর একটি মৌলিক সমস্যা ছিল: এটি একটি পরম তারিখ ব্যবহার করত যা সার্ভার এবং ক্লায়েন্ট সময় অঞ্চলের উপর নির্ভরশীল ছিল। Cache-Control আপেক্ষিক সময়ে (প্রতিক্রিয়া পাওয়ার মুহূর্ত থেকে সেকেন্ডে max-age) স্যুইচ করে এই সমস্যার সমাধান করে। পরে, RFC 7234 (2014)-এ, নতুন নির্দেশাবলী যুক্ত করা হয়েছিল: স্ট্যাটিক অ্যাসেটের জন্য immutable, বিলম্বিত যাচাইয়ের জন্য stale-while-revalidate এবং stale-if-error।
Cache-Control তিনটি গ্রুপে বিভক্ত 10টিরও বেশি নির্দেশ অন্তর্ভুক্ত করে: অনুরোধ নির্দেশাবলী (ক্লায়েন্ট → সার্ভার), প্রতিক্রিয়া নির্দেশাবলী (সার্ভার → ক্লায়েন্ট), এবং এক্সটেনশন। অনুশীলনে, মোবাইল ডেভেলপমেন্ট 6-7টি প্রধান প্রতিক্রিয়া নির্দেশ ব্যবহার করে যা 95% ক্যাশিং পরিস্থিতি কভার করে। আসুন প্রতিটি উদাহরণ এবং সুপারিশ সহ দেখি।
| নির্দেশ | অর্থ | উদাহরণ |
|---|---|---|
| max-age | প্রতিক্রিয়ার মুহূর্ত থেকে সেকেন্ডে জীবনকাল | max-age=3600 — 1 ঘন্টা |
| s-maxage | শেয়ার্ড ক্যাশের জন্য max-age (প্রক্সি, CDN) | s-maxage=86400 — CDN-এর জন্য 1 দিন |
| public | সবার ক্যাশিং অনুমতি দেয় (প্রক্সি সহ) | public, max-age=3600 |
| private | শুধুমাত্র ব্রাউজার/অ্যাপ্লিকেশনের জন্য ক্যাশ অনুমতি দেয় | private, max-age=600 |
| no-cache | যাচাই ছাড়া ব্যবহার করবেন না (304 প্রয়োজন) | no-cache |
| no-store | সম্পূর্ণরূপে ক্যাশিং নিষিদ্ধ করুন | no-store |
| must-revalidate | max-age-এর পরে, মূল সার্ভারের সাথে পুনরায় যাচাই করতে হবে | max-age=3600, must-revalidate |
| immutable | রিসোর্স পরিবর্তন হবে না (সংস্করণযুক্ত স্ট্যাটিক অ্যাসেটের জন্য) | max-age=31536000, immutable |
max-age সবচেয়ে গুরুত্বপূর্ণ নির্দেশ। এটি নির্দিষ্ট সময়ের জন্য ক্লায়েন্টকে সার্ভারে অনুরোধ করতে নিষেধ করে। স্ট্যাটিক অ্যাসেটের (CSS, JS, ইমেজ) জন্য, max-age সাধারণত 1 দিন থেকে 1 বছর পর্যন্ত সেট করা হয়। API প্রতিক্রিয়ার জন্য — 0 সেকেন্ড (সবসময় তাজা ডেটা) থেকে 5-10 মিনিট (রেফারেন্স ডেটা) পর্যন্ত। s-maxage CDN এবং ব্রাউজারের জন্য আলাদা জীবনকাল নির্ধারণের অনুমতি দেয়: CDN 1 দিনের জন্য একটি কপি সংরক্ষণ করে, ব্রাউজার 1 ঘন্টার জন্য।
এই দুটি নির্দেশ প্রায়ই বিভ্রান্ত হয়। no-cache ক্যাশিং নিষিদ্ধ করে না — এটি প্রতিটি ব্যবহারে শর্তসাপেক্ষ অনুরোধের (If-Modified-Since বা If-None-Match) মাধ্যমে ক্যাশ করা কপি যাচাই প্রয়োজন। যদি সার্ভার 304 দিয়ে প্রতিক্রিয়া জানায় — ক্লায়েন্ট ক্যাশ ব্যবহার করে। যদি 200 — এটি আপডেট করে। অন্যদিকে, no-store, ডিস্ক এবং মেমরি সহ যেকোনো ক্যাশে প্রতিক্রিয়া সংরক্ষণ সম্পূর্ণরূপে নিষিদ্ধ করে। শুধুমাত্র সংবেদনশীল ডেটার জন্য no-store ব্যবহার করুন — টোকেন, পেমেন্ট ডেটা, ব্যক্তিগত নথি।
Expires হেডার (HTTP/1.0)ও রিসোর্সের জীবনকাল নির্দিষ্ট করে কিন্তু একটি পরম তারিখ ব্যবহার করে: Expires: Thu, 03 Jul 2026 12:00:00 GMT। Cache-Control max-age প্রতিক্রিয়ার মুহূর্ত থেকে আপেক্ষিক সময় ব্যবহার করে। পার্থক্যটি ডিস্ট্রিবিউটেড সিস্টেমের জন্য গুরুত্বপূর্ণ: যদি সার্ভার এবং ক্লায়েন্ট বিভিন্ন সময় অঞ্চলে থাকে, তাহলে Expires ভুলভাবে ব্যাখ্যা করা যেতে পারে। Cache-Control-এর এই সমস্যা নেই — 3600 সেকেন্ড সবসময় 3600 সেকেন্ড।
যখন উভয় হেডার উপস্থিত থাকে, Cache-Control Expires-এর উপর অগ্রাধিকার পায়। এটি RFC 7234-এ সংজ্ঞায়িত: "যদি একটি প্রতিক্রিয়াতে max-age নির্দেশ সহ Cache-Control ফিল্ড থাকে, তাহলে প্রাপককে Expires ফিল্ড উপেক্ষা করতে হবে।" অনুশীলনে, আধুনিক ক্লায়েন্টদের জন্য Expires একেবারেই না ফেরানোর পরামর্শ দেওয়া হয়, কারণ Cache-Control সমস্ত Expires পরিস্থিতি কভার করে। তবে, পুরানো প্রক্সি এবং ব্রাউজারগুলির সাথে পশ্চাদগামী সামঞ্জস্যের জন্য, উভয় হেডার ফেরত দেওয়া যেতে পারে।
Expires মূলত Nginx এবং Apache-তে স্ট্যাটিক কন্টেন্টের জন্য টিকে আছে — এই সার্ভারগুলি স্বয়ংক্রিয়ভাবে উভয় হেডার যোগ করে। যদি আপনার প্রকল্প Cache-Control ছাড়া Expires-এর সম্মুখীন হয়, তাহলে এটি max-age সহ Cache-Control দিয়ে প্রতিস্থাপন করুন: ক্যাশ নিয়ন্ত্রণের নির্ভুলতা উন্নত হয় এবং সময় অঞ্চলের উপর নির্ভরতা দূর হয়। মাইগ্রেশনের জন্য, Expires-এর পরিবর্তে Cache-Control যোগ করার জন্য সার্ভার কনফিগার করা যথেষ্ট।
# Nginx: Cache-Control স্ট্যাটিক ফাইলের জন্য
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable, max-age=2592000";
}
# বিভিন্ন ধরনের কন্টেন্টের জন্য বিভিন্ন নীতি
location /api/config {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
location /api/static-data {
expires 5m;
add_header Cache-Control "public, max-age=300";
}
Nginx কনফিগারেশনে, স্ট্যাটিক ফাইলগুলি (CSS, JS, ইমেজ) immutable অ্যাট্রিবিউট সহ 30 দিনের জন্য Cache-Control-এ সেট করা হয় — এই অ্যাট্রিবিউট ব্রাউজারকে জানায় যে রিসোর্স এই URL-এ কখনও পরিবর্তন হয় না (ফাইলের নামে হ্যাশের মাধ্যমে সংস্করণীকরণ)। API এন্ডপয়েন্টগুলি ডায়নামিক ডেটার জন্য no-cache এবং রেফারেন্স ডেটার জন্য ছোট max-age সহ public ব্যবহার করে — প্রায়শই অনুরোধ করা এবং খুব কমই পরিবর্তনশীল তালিকা।
মোবাইল অ্যাপ্লিকেশনে, Cache-Control মোবাইল নেটওয়ার্কের সীমাবদ্ধতার কারণে একটি বিশেষ ভূমিকা পালন করে: উচ্চ বিলম্ব, অস্থির সংযোগ, ট্রাফিক সীমা। সঠিক ক্যাশিং ব্যবহারকারীকে তাত্ক্ষণিকভাবে ডেটা প্রদর্শন করতে দেয়, এমনকি অফলাইনেও, এবং এটি ব্যাকগ্রাউন্ডে আপডেট করতে দেয়। Android-এ OkHttp এবং iOS-এ URLSession-এ বিল্ট-ইন ক্যাশিং সিস্টেম রয়েছে যা Cache-Control সম্মান করে।
OkHttp CacheInterceptor ব্যবহার করে, যা প্রতিক্রিয়া থেকে Cache-Control পড়ে এবং স্বয়ংক্রিয়ভাবে ক্যাশিং পরিচালনা করে। যদি সার্ভার Cache-Control: max-age=3600 রিটার্ন করে, OkHttp এক ঘন্টার জন্য সার্ভারে অনুরোধ করবে না। max-age শেষ হওয়ার পরে, OkHttp If-Modified-Since এবং If-None-Match সহ একটি শর্তসাপেক্ষ অনুরোধ পাঠায়। OkHttp-এ ক্যাশ কনফিগারেশন: OkHttpClient.Builder().cache(Cache(directory, maxSize)).
fun createCachedClient(cacheDir: File): OkHttpClient {
return OkHttpClient.Builder()
.cache(Cache(cacheDir, 10L * 1024 * 1024))
.addNetworkInterceptor { chain ->
val response = chain.proceed(chain.request())
response.newBuilder()
.header("Cache-Control",
"public, max-age=300")
.removeHeader("Pragma")
.build()
}
.build()
}
কোডটি 10 MB ক্যাশ সহ একটি OkHttpClient তৈরি করে এবং NetworkInterceptor-এর মাধ্যমে Cache-Control ওভাররাইড করে। যদি সার্ভার Cache-Control রিটার্ন না করে বা Expires ব্যবহার করে, ইন্টারসেপ্টর public, max-age=300 (5 মিনিট) যোগ করে। ইন্টারসেপ্টর সামঞ্জস্যের জন্য পুরানো Pragma হেডার (HTTP/1.0) সরিয়ে দেয়। iOS-এ ক্যাশিং memoryCapacity এবং diskCapacity সেটিংস সহ URLCache.shared-এর মাধ্যমে একইভাবে কাজ করে।
stale-while-revalidate নির্দেশ ব্যবহারকারীকে পুরানো ক্যাশ দেখানোর অনুমতি দেয় যখন অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে তাজা ডেটা আনে। এটি তাত্ক্ষণিক প্রতিক্রিয়া প্রভাব প্রদান করে: ব্যবহারকারী অবিলম্বে কন্টেন্ট দেখে এবং এক সেকেন্ড পরে এটি বর্তমান সংস্করণে আপডেট হয়। OkHttp সংস্করণ 3.10 থেকে এবং iOS 14+-এ URLCache দ্বারা সমর্থিত। উদাহরণ: Cache-Control: max-age=3600, stale-while-revalidate=300 — 1 ঘন্টা তাজা ক্যাশ, তারপর ব্যাকগ্রাউন্ড রিফ্রেশের সাথে 5 মিনিট পুরানো ডেটা দেখানো।
বিভিন্ন রিসোর্স প্রকারের বিভিন্ন ক্যাশিং কৌশল প্রয়োজন। আসুন মোবাইল ডেভেলপমেন্টে সাধারণ পরিস্থিতির জন্য সর্বোত্তম কনফিগারেশন দেখি। ফাইলের নামে হ্যাশ সহ স্ট্যাটিক কন্টেন্টের (bundle.abc123.js) জন্য, আপনি immutable সহ max-age 1 বছর পর্যন্ত সেট করতে পারেন। খুব কমই আপডেট হওয়া API তালিকার (ডিরেক্টরি, ক্যাটাগরি) জন্য — stale-while-revalidate সহ 5 মিনিট থেকে 1 ঘন্টা পর্যন্ত max-age।
| রিসোর্স প্রকার | Cache-Control | ব্যাখ্যা |
|---|---|---|
| সংস্করণযুক্ত স্ট্যাটিক অ্যাসেট | public, max-age=31536000, immutable | 1 বছর, ফাইল পরিবর্তন হয় না (URL-এ হ্যাশ) |
| অ-সংস্করণযুক্ত স্ট্যাটিক অ্যাসেট | public, max-age=86400, must-revalidate | পরে বাধ্যতামূলক পুনরায় যাচাই সহ 1 দিন |
| API: রেফারেন্স ডেটা | public, max-age=600, stale-while-revalidate=60 | 10 মিনিট ক্যাশ + 1 মিনিট পুরানো |
| API: ব্যবহারকারীর ডেটা | private, max-age=60 | 1 মিনিট, শুধুমাত্র একটি নির্দিষ্ট ব্যবহারকারীর জন্য |
| API: সংবেদনশীল ডেটা | no-store | সম্পূর্ণ ক্যাশ নিষেধাজ্ঞা |
| HTML পৃষ্ঠা | no-cache, must-revalidate | প্রতি অনুরোধে যাচাই, অপরিবর্তিত থাকলে 304 |
নিরাপত্তা মনে রাখা গুরুত্বপূর্ণ: ব্যক্তিগত ব্যবহারকারীর ডেটা ধারণকারী প্রতিক্রিয়ার জন্য, সর্বদা private সেট করুন। এই নির্দেশ ছাড়া, একটি পাবলিক প্রক্সি (যেমন, কর্পোরেট) প্রতিক্রিয়া ক্যাশ করতে পারে এবং এটি অন্য ব্যবহারকারীকে দিতে পারে। প্রমাণীকরণ টোকেন এবং পেমেন্ট তথ্যের জন্য, no-store ব্যবহার করুন — এমনকি একটি প্রাইভেট ক্যাশেরও এই ডেটা ডিস্কে সংরক্ষণ করা উচিত নয়।
Cache-Control সঠিকতা যাচাই করতে, Age হেডার (ক্যাশ কত সেকেন্ড ধরে সংরক্ষিত) এবং X-Cache (CDN-এ hit/miss) ব্যবহার করুন। ব্রাউজারে — Network ট্যাব, Size কলাম "from disk cache" বা "304 Not Modified" দেখায়। যদি একটি রিসোর্স ক্যাশ করা উচিত কিন্তু প্রতিবার লোড হয়, তাহলে পরীক্ষা করুন যে সার্ভার আপনার নির্দেশের সাথে Cache-Control: no-cache বা Pragma: no-cache যোগ করছে কিনা।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
max-age সব ক্যাশে প্রযোজ্য (ব্রাউজার সহ), s-maxage শুধুমাত্র শেয়ার্ড ক্যাশে (প্রক্সি, CDN) প্রযোজ্য। যদি s-maxage নির্দিষ্ট করা থাকে, CDN max-age উপেক্ষা করে এবং s-maxage ব্যবহার করে। এটি ব্রাউজার এবং CDN-এর জন্য আলাদা জীবনকাল নির্ধারণের অনুমতি দেয়।
না, max-age সহ প্রতিক্রিয়া পাঠানোর পরে, ক্লায়েন্ট টাইমার শেষ না হওয়া পর্যন্ত অনুরোধ করবে না। তাৎক্ষণিক ক্যাশ ইনভ্যালিডেশনের জন্য, আপনাকে রিসোর্স URL পরিবর্তন করতে হবে (সংস্করণ/হ্যাশ যোগ করুন) এবং জোরপূর্বক রিসেটের জন্য push নোটিফিকেশন বা WebSocket বার্তা পাঠাতে হবে।
immutable নির্দেশ (RFC 8246) ব্রাউজারকে জানায় যে রিসোর্স এই URL-এ কখনও পরিবর্তন হবে না। পৃষ্ঠা রিফ্রেশ করার সময় ব্রাউজার একটি শর্তসাপেক্ষ অনুরোধ করার চেষ্টাও করে না — এটি max-age শেষ না হওয়া পর্যন্ত ক্যাশ ব্যবহার করে। শুধুমাত্র সংস্করণযুক্ত ফাইলের সাথে কাজ করে।
Googlebot Cache-Control বিবেচনা করে: দীর্ঘ ক্যাশিং বারবার ক্রলিং গতি বাড়ায়। দ্রুত ক্যাশের সাথে noindex ঠিক আছে। no-store ইনডেক্সিং ধীর করতে পারে কারণ Googlebot প্রতিবার পৃষ্ঠাটি স্ক্র্যাচ থেকে লোড করবে। খুব ছোট max-age ক্রলিংয়ের সময় সার্ভার লোড বাড়ায়।
helmet বা middleware-এর মাধ্যমে: res.set('Cache-Control', 'public, max-age=3600'). স্ট্যাটিক ফাইলের জন্য, maxAge প্যারামিটার সহ express.static ব্যবহার করুন: express.static('public', {maxAge: '1y'}). ডায়নামিক রুটের জন্য — প্রতিটি হ্যান্ডলারে পৃথকভাবে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন