Caching یعنی ذخیرهسازی موقت داده یا Response در یک لایهی میانی یا محلی، بهطوری که برای درخواستهای بعدی لازم نباشد همان داده دوباره از منبع اصلی مثل Database، Server یا Origin خوانده شود.
هدف اصلی Caching افزایش Performance، کاهش Latency، کاهش بار روی Backend و بهبود Scalability است.
در تست API و Backend، Caching فقط موضوع سرعت نیست؛ بلکه یک موضوع مهم درستی داده هم هست. چون اگر Cache درست مدیریت نشود، ممکن است دادهی قدیمی (stale data) برگردد، تغییرات جدید دیده نشود، یا بین DB و Response ناسازگاری ایجاد شود.
چون خیلی از باگهای واقعی در سیستمهای Backend و بانکی فقط از خود Business Logic نیستند؛ از Cache behavior میآیند.
مثلاً:
اطلاعات مشتری در DB تغییر کرده ولی API هنوز مقدار قبلی را از Cache برمیگرداند
کاربر Logout کرده ولی Client-side cache هنوز دادهی حساس را نگه داشته
فایل JS/CSS جدید deploy شده ولی CDN هنوز نسخهی قبلی را سرو میکند
ETag یا Cache-Control اشتباه باعث میشود کلاینت دادهی بهروز نگیرد
پس تستر باید بفهمد:
داده از کدام لایه cache میشود
چه زمانی cache معتبر است و چه زمانی باید invalidate شود
چه HTTP caching headerهایی رفتار cache را کنترل میکنند
Caching را در این سرفصل میتوان در سه لایهی اصلی دید:
Client-side caching
Server-side caching
Proxy / CDN caching
در این مدل، داده در سمت Client یا User Agent ذخیره میشود؛ یعنی در Browser، Mobile App یا محیط کلاینت.
هدف این است که کلاینت برای هر بار نمایش یا هر بار درخواست، دوباره همهچیز را از سرور نگیرد.
مرورگر فایلها یا پاسخها را بهصورت محلی ذخیره میکند تا در درخواستهای بعدی سریعتر استفاده شوند.
معمولاً برای اینها زیاد استفاده میشود:
Images
CSS
JavaScript
گاهی API responses یا فایلهای HTML
اگر Cache-Control، ETag یا Expires درست تنظیم شده باشند، مرورگر میتواند تصمیم بگیرد که از نسخهی محلی استفاده کند یا دوباره با سرور چک کند.
Cookie یک دادهی کوچک است که در سمت مرورگر ذخیره میشود و معمولاً برای session, authentication, tracking یا preference استفاده میشود.
Cookie ذاتاً cache به معنای classic caching نیست، ولی چون دادهای را در سمت کلاینت نگه میدارد، در این سرفصل کنار client-side storage دیده میشود.
از دید تست:
آیا اطلاعات حساس در Cookie ذخیره شده؟
آیا HttpOnly / Secure / SameSite رعایت شده؟
آیا بعد از logout یا session expiry، دادهی قدیمی هنوز معتبر است؟
localStorage یک فضای ذخیرهسازی سمت مرورگر است که داده را بهصورت key-value نگه میدارد و حتی بعد از بستن مرورگر هم باقی میماند.
معمولاً برای:
preferenceها
بعضی دادههای UI
draftها
token یا دادههای موقت
از دید تست:
آیا دادهی حساس مثل Access Token یا اطلاعات شخصی در localStorage نگهداری شده؟
آیا بعد از logout یا reset session داده پاک میشود؟
آیا دادهی قدیمی باعث نمایش stale UI میشود؟
Service Worker اسکریپتی در مرورگر است که بین Browser و Network قرار میگیرد و میتواند درخواستها را intercept کند، فایلها را cache کند و تجربهی offline یا PWA را ممکن سازد.
مثلاً ممکن است:
فایلهای static را cache کند
responseهای خاص را ذخیره کند
در حالت offline نسخهی cached را برگرداند
از دید تست:
آیا بعد از release جدید، فایلهای قدیمی هنوز از service worker برمیگردند؟
آیا دادهی offline و online درست sync میشود؟
آیا cache invalidation در PWA درست انجام میشود؟
در این مدل، داده در سمت Server یا در یک لایهی نزدیک به backend ذخیره میشود تا برای درخواستهای بعدی لازم نباشد دوباره محاسبه یا از Database خوانده شود.
این مدل معمولاً برای:
API responses
Query results
session data
computed results
reference data
استفاده میشود.
گاهی پاسخ یک endpoint در سرور cache میشود.
مثلاً اگر endpoint مربوط به لیست شعب بانک یا لیست کد کشورها باشد، لازم نیست هر بار از DB خوانده شود؛ میتوان response را مدتی cache کرد.
مزیت:
کاهش فشار روی DB
افزایش سرعت پاسخ
بهبود throughput
ریسک:
اگر داده تغییر کند ولی cache invalidate نشود، API stale response میدهد
در این مدل داده در حافظهی RAM خود اپلیکیشن یا سرویس ذخیره میشود.
مثلاً:
mapهای درونبرنامهای
in-process cache
object cache
مزیت:
بسیار سریع
ساده برای دادههای سبک و پرتکرار
محدودیت:
معمولاً بین چند instance مشترک نیست
با restart سرویس از بین میرود
در سیستم distributed میتواند باعث cache inconsistency بین instanceها شود
Redis یکی از رایجترین ابزارهای in-memory cache و key-value store است.
در Backend از Redis برای این موارد زیاد استفاده میشود:
caching API result
session storage
rate limiting
token blacklist
temporary business data
distributed lock
مزیتهای Redis:
سریع
مناسب برای حجم زیاد درخواست
TTL و expiration دارد
در معماری distributed کاربردی است
از دید تست:
آیا داده بعد از update در DB در Redis invalidate میشود؟
آیا TTL درست تنظیم شده؟
آیا cache key درست طراحی شده؟
آیا دادهی قدیمی از Redis برمیگردد؟
یعنی وقتی دادهی اصلی تغییر میکند، Cache باید بهروز، حذف یا refresh شود تا دادهی قدیمی برنگردد.
این یکی از مهمترین بخشهای تست caching است.
مثال:
نام مشتری در DB تغییر میکند
ولی GET /customers/123 هنوز نام قبلی را از Redis برمیگرداند
این یعنی stale cache یا failure در cache invalidation
CDN یا Content Delivery Network شبکهای از سرورهای توزیعشده است که محتوای static را نزدیکتر به کاربر cache و سرو میکند.
معمولاً برای اینها استفاده میشود:
images
CSS
JavaScript
fonts
و گاهی بعضی responseهای cacheable
هدف:
کاهش latency
کاهش بار روی origin server
افزایش سرعت لود
گاهی بین Client و Server یک Proxy یا Gateway وجود دارد که responseها را cache میکند.
این لایه میتواند:
درخواستهای تکراری را سریعتر پاسخ دهد
بار backend را کم کند
ولی اگر نادرست تنظیم شود، دادهی قدیمی یا اشتباه بدهد
فایل JS/CSS جدید deploy شده ولی CDN نسخهی قبلی را میدهد
تصویر یا asset جدید به کاربر نمایش داده نمیشود
endpointی که نباید cache شود، اشتباهی cache شده
response مخصوص یک کاربر به کاربر دیگر leak شود اگر cache policy اشتباه باشد
بخش خیلی مهم این سرفصل همینجاست.
این Headerها تعیین میکنند Client، Proxy یا CDN چگونه و تا چه مدت response را cache کنند.
مهمترین Header برای کنترل رفتار cache است.
با Cache-Control مشخص میکنیم:
آیا response cacheable هست یا نه
کجا cache شود
چه مدت معتبر بماند
آیا قبل از استفاده باید revalidate شود یا نه
مثال:
Cache-Control: max-age=3600
یعنی response تا 3600 ثانیه معتبر است و میتواند از cache استفاده شود.
مدت اعتبار response در cache را مشخص میکند.
مثال:
Cache-Control: max-age=600
یعنی تا 10 دقیقه response میتواند از cache استفاده شود.
اسمش گمراهکننده است.
no-cache لزوماً یعنی «اصلاً cache نکن» نیست؛ یعنی قبل از استفاده از نسخهی cached باید با سرور revalidate شود.
یعنی response اصلاً نباید ذخیره شود؛ نه در browser cache، نه در proxy cache.
برای دادههای حساس مثل:
اطلاعات حساب
اطلاعات شخصی
پاسخهای امنیتی
خیلی مهم است.
یعنی response میتواند در cacheهای shared مثل CDN یا proxy هم ذخیره شود.
یعنی response مخصوص یک کاربر است و نباید در cacheهای shared ذخیره شود؛ فقط cache خصوصی client مجاز است.
برای responseهای شخصی یا auth-based خیلی مهم است.
ETag یک شناسهی نسخه یا fingerprint برای یک resource است.
Server همراه response یک ETag میدهد، مثلاً:
ETag: "v1-customer-123"
بعد در درخواست بعدی، Client میتواند بگوید:
If-None-Match: "v1-customer-123"
اگر resource تغییر نکرده باشد، Server میتواند بهجای برگرداندن کل body، فقط 304 Not Modified بدهد.
کاهش حجم response
revalidation هوشمند
تشخیص تغییر یا عدم تغییر resource
باید بررسی کنی:
آیا بعد از تغییر داده، ETag هم تغییر میکند؟
آیا If-None-Match درست کار میکند؟
آیا در صورت unchanged بودن resource، 304 برمیگردد؟
زمان آخرین تغییر resource را نشان میدهد.
مثال:
Last-Modified: Wed, 25 Jun 2026 10:00:00 GMT
بعد Client میتواند در request بعدی بگوید:
If-Modified-Since: Wed, 25 Jun 2026 10:00:00 GMT
اگر از آن زمان چیزی تغییر نکرده باشد، Server میتواند 304 Not Modified بدهد.
Last-Modified مبتنی بر زمان آخرین تغییر است
ETag مبتنی بر نسخه/شناسهی محتواست و معمولاً دقیقتر است
یک Header قدیمیتر برای مشخصکردن زمان انقضای cache است.
مثال:
Expires: Wed, 25 Jun 2026 12:00:00 GMT
یعنی تا آن زمان response میتواند از cache استفاده شود.
امروزه معمولاً Cache-Control مهمتر و رایجتر از Expires است، ولی ممکن است هر دو را ببینی.
این Status Code در caching خیلی مهم است.
وقتی Client با If-None-Match یا If-Modified-Since درخواست میفرستد و resource تغییر نکرده، Server میتواند 304 Not Modified بدهد؛ یعنی:
body جدید لازم نیست
از نسخهی cached استفاده کن
یعنی دادهای که از cache برگشته ولی دیگر نسخهی بهروز سیستم نیست.
مثلاً:
مشتری آدرسش را تغییر داده
در DB درست ذخیره شده
ولی API هنوز آدرس قبلی را از cache برمیگرداند
این یکی از مهمترین failureهای مرتبط با caching است.
درخواست از cache پاسخ گرفته و لازم نبوده به منبع اصلی برود.
داده در cache نبوده یا منقضی شده و سیستم مجبور شده از DB، origin یا backend داده را دوباره بگیرد.
این دو مفهوم برای تحلیل performance و debugging مهماند.
Backend Tester باید بتواند:
تشخیص دهد داده از DB آمده یا از Cache
ریسک stale data را در سناریوهای update و read بررسی کند
Cache-Control, ETag, Last-Modified, Expires را تحلیل کند
فرق client-side, server-side و CDN caching را بداند
بعد از تغییر داده، invalidation و refresh را تست کند
تشخیص دهد چه responseهایی private هستند و نباید shared cache شوند
در پاسخ امتحانی فقط نگویید:
caching برای افزایش سرعت است.
این جواب ضعیف است. پاسخ خوب باید این کلیدواژهها را داشته باشد:
client-side cache, server-side cache, CDN/proxy cache, stale data, cache invalidation, Cache-Control, ETag, Last-Modified, Expires, 304 Not Modified, performance vs data freshness
Caching مکانیزمی برای ذخیرهسازی موقت داده یا response در لایههای مختلف سیستم است تا درخواستهای بعدی سریعتر پاسخ داده شوند و بار روی backend کاهش یابد. Cache میتواند در سمت Client مثل browser cache، localStorage و service worker، در سمت Server مثل memory cache یا Redis، یا در لایههای Proxy/CDN انجام شود. در تست API، caching فقط مسئلهی performance نیست، بلکه مسئلهی data freshness و جلوگیری از stale response هم هست. برای کنترل caching در HTTP از Headerهایی مثل Cache-Control, ETag, Expires و Last-Modified استفاده میشود و تستر باید بررسی کند که بعد از تغییر داده، cache درست invalidate شود و response قدیمی برنگردد.
Caching Client-side Cache Browser Cache Cookies localStorage Service Worker Server-side Cache Redis Memory Cache CDN Proxy Cache Cache Invalidation Stale Data Cache-Control ETag Expires Last-Modified If-None-Match If-Modified-Since 304 Not Modified Cache Hit Cache Miss Performance Latency Data Freshness
Caching (ذخیرهسازی موقت داده یا response برای استفادهی سریعتر در درخواستهای بعدی): برای بهبود Performance، کاهش Latency و کاهش بار روی Backend استفاده میشود.
Client-side Cache (ذخیرهسازی داده در سمت Client مثل Browser یا App): برای کاهش درخواستهای تکراری و بهبود سرعت نمایش داده در سمت کاربر استفاده میشود.
Browser Cache (کش داخلی مرورگر برای فایلها و responseها): برای ذخیرهی CSS، JS، Image و گاهی responseهای API استفاده میشود.
Cookies (دادههای کوچک ذخیرهشده در مرورگر): برای session، authentication، tracking یا preference استفاده میشوند و باید از نظر امنیتی و ماندگاری بررسی شوند.
localStorage (فضای ذخیرهسازی key-value در مرورگر): برای نگهداری دادههای UI، draftها یا بعضی tokenها استفاده میشود و ریسک نگهداری دادهی حساس دارد.
Service Worker (اسکریپت واسط بین Browser و Network): برای offline support، PWA caching و intercept کردن requestها استفاده میشود.
Server-side Cache (کش در سمت سرور یا لایه نزدیک به backend): برای ذخیرهی API response، query result یا دادههای پرتکرار بهکار میرود.
Redis (in-memory key-value store پرکاربرد برای caching): برای API response caching، session storage، rate limiting و دادههای موقت استفاده میشود.
Memory Cache (کش داخل حافظهی اپلیکیشن): برای دسترسی سریع به دادههای پرتکرار استفاده میشود ولی معمولاً بین چند instance مشترک نیست.
CDN (شبکهی توزیع محتوا برای cache و تحویل سریعتر فایلهای static): برای image، CSS، JS و کاهش latency در کاربران جغرافیایی مختلف استفاده میشود.
Proxy Cache (کش در لایهی میانی بین Client و Server): برای کاهش بار backend و پاسخ سریعتر به درخواستهای تکراری استفاده میشود.
Cache Invalidation (حذف یا بهروزرسانی cache پس از تغییر دادهی اصلی): برای جلوگیری از stale data و ناسازگاری بین cache و DB حیاتی است.
Stale Data (دادهی قدیمیای که هنوز از cache برمیگردد): یکی از failureهای مهم در تست API و backend است.
Cache-Control (Header اصلی برای کنترل رفتار cache): برای تعیین max-age، no-store، no-cache، public و private استفاده میشود.
ETag (شناسه یا fingerprint نسخهی یک resource): برای cache revalidation و تشخیص تغییر یا عدم تغییر resource استفاده میشود.
Expires (زمان انقضای response در cache): Header قدیمیتر برای تعیین زمان اعتبار cache است.
Last-Modified (زمان آخرین تغییر resource): برای conditional request و تشخیص تغییر resource استفاده میشود.
If-None-Match (Header درخواست برای ارسال ETag قبلی به سرور): در revalidation استفاده میشود تا اگر resource تغییر نکرده بود، 304 برگردد.
If-Modified-Since (Header درخواست بر اساس زمان آخرین تغییر): برای conditional request بر مبنای Last-Modified استفاده میشود.
304 Not Modified (Status Code مربوط به unchanged بودن resource): به Client میگوید از نسخهی cached استفاده کند و body جدید لازم نیست.
Cache Hit (پاسخگرفتن از cache): نشان میدهد داده از cache برگشته و نیازی به مراجعه به منبع اصلی نبوده است.
Cache Miss (نبودن داده در cache یا منقضی شدن آن): باعث میشود سیستم از DB، backend یا origin داده را دوباره بگیرد.
Performance (کارایی و سرعت پاسخگویی سیستم): یکی از مهمترین اهداف استفاده از caching است.
Latency (زمان تأخیر در پاسخ): caching با نزدیکتر کردن داده به مصرفکننده، latency را کاهش میدهد.
Data Freshness (بهروز بودن دادهی نمایشدادهشده): در تست caching باید مطمئن شد cache باعث نمایش دادهی قدیمی نشده است.
GET /v1/customers/12345 با token معتبر.Expected API/Cache /strong>
Response نباید Cache-Control: public داشته باشد. برای داده حساس باید no-store یا حداقل private باشد.
Expected Client/CDN /strong>
CDN/Proxy نباید response مشتری را cache کند.
Risk Covered:
Data leakage از shared cache.
Cache Busting: تغییر نام یا version فایل static برای مجبور کردن browser/CDN به گرفتن نسخه جدید.
Stale Response: پاسخ قدیمی که از cache برگشته و با DB هماهنگ نیست.
Cache Consistency: هماهنگی بین دادهی cache و منبع اصلی مثل DB.
Shared Cache: cache مشترک مثل CDN/Proxy که نباید دادهی شخصی در آن ذخیره شود.
no-store: یعنی response اصلاً ذخیره نشود؛ مناسب دادههای حساس.