CRUD ऐप्स में डुप्लिकेट रिकॉर्ड रोकने के लिए कई परतों वाली सुरक्षा चाहिए: डेटाबेस यूनिक कॉन्स्ट्रेंट्स, idempotency कीज़, और डबल सबमिट रोकने वाली UI स्थितियाँ।

डुप्लिकेट रिकॉर्ड तब होता है जब आपकी ऐप एक ही चीज़ को दो बार स्टोर कर देती है। यह वही चेकआउट के लिए दो ऑर्डर हो सकते हैं, एक ही विवरण वाले दो सपोर्ट टिकट, या एक ही साइनअप फ्लो से बने दो अकाउंट। CRUD ऐप में डुप्लिकेट्स अक्सर सामान्य पंक्तियों की तरह दिखते हैं, पर जब आप पूरे डेटा को देखते हैं तो वे गलत होते हैं।
अधिकांश डुप्लिकेट सामान्य व्यवहार से शुरू होते हैं। कोई व्यक्ति Create पर दो बार क्लिक कर देता है क्योंकि पेज धीमा महसूस होता है। मोबाइल पर डबल टैप आसानी से अनदेखा हो सकता है। यहां तक कि सावधान यूज़र भी फिर से ट्राय कर लेते हैं अगर बटन सक्रिय दिखता रहे और कोई स्पष्ट संकेत न हो कि कुछ हो रहा है।
फिर आता है जटिल मध्य भाग: नेटवर्क और सर्वर। एक रिक्वेस्ट टाइमआउट कर सकती है और स्वचालित रूप से रिट्राई हो सकती है। कोई क्लाइंट लाइब्रेरी POST दोहरा सकती है अगर उसे लगे कि पहली कोशिश फेल हो गई। पहली रिक्वेस्ट सफल हो सकती है, पर रिस्पॉन्स खो सकता है, इसलिए यूज़र फिर से कोशिश करता है और एक दूसरी कॉपी बन जाती है।
आप इसे केवल एक परत से हल नहीं कर सकते क्योंकि हर परत कहानी का केवल एक हिस्सा देखती है। UI आकस्मिक डबल सबमिट घटा सकता है, पर यह खराब कनेक्शनों से होने वाली रिट्राईज़ को नहीं रोक सकता। सर्वर दोहराव पहचान सकता है, पर उसे यह पहचानने का भरोसेमंद तरीका चाहिए कि “यह वही create फिर से है।” डेटाबेस नियम लागू कर सकता है, पर तभी जब आप स्पष्ट रूप से परिभाषित करें कि “एक ही चीज़” का मतलब क्या है।
लक्ष्य सरल है: बनाएँ सुरक्षित हों भले ही वही रिक्वेस्ट दो बार आए। दूसरी कोशिश को no-op, “पहले से बना हुआ” रेस्पॉन्स, या नियंत्रित कॉन्फ्लिक्ट बन जाना चाहिए—not एक दूसरी पंक्ति।
कई टीमें डुप्लिकेट्स को डेटाबेस की समस्या समझती हैं। असल में, डुप्लिकेट्स ज़्यादातर पहले पैदा होते हैं, जब वही क्रिएट क्रिया एक से ज्यादा बार ट्रिगर हो जाती है।
यूज़र Create पर क्लिक करता है और कुछ नहीं होता दिखता, तो वह फिर से क्लिक कर देता है। या वे Enter दबाते हैं, फिर तुरंत बटन क्लिक करते हैं। मोबाइल पर आप दो तेज़ टैप, ओवरलैपिंग टच और क्लिक इवेंट्स, या ऐसा जेस्चर पा सकते हैं जो दो बार रजिस्टर हो।
भले ही यूज़र केवल एक बार सबमिट करे, नेटवर्क फिर भी रिक्वेस्ट दोहरा सकता है। टाइमआउट रिट्राई ट्रिगर कर सकता है। एक ऑफ़लाइन ऐप “Save” को कतारबद्ध कर सकता है और पुन: कनेक्ट पर सब भेज सकता है। कुछ HTTP लाइब्रेरीज़ कुछ त्रुटियों पर स्वतः ही रिट्राई करती हैं, और आप तब तक नोटिस नहीं करेंगे जब तक डुप्लिकेट पंक्तियाँ न दिखें।
सर्वर जानबूझकर काम दोहराते हैं। जॉब क्यूज़ फेल हुए जॉब्स को रिट्राई करते हैं। वेबहुक प्रोवाइडर अक्सर एक इवेंट को कई बार भेजते हैं, खासकर अगर आपका एंडपॉइंट धीमा है या non-2xx status लौटाता है। अगर आपका क्रिएट लॉजिक इन इवेंट्स से ट्रिगर होता है, तो मान कर चलें कि डुप्लिकेट होंगे।
कॉन्करेंसी सबसे छिपे हुए डुप्लिकेट बनाती है। दो टैब मिलीसेकंड्स के भीतर एक ही फॉर्म सबमिट कर देते हैं। अगर आपका सर्वर पहले “क्या यह पहले से मौजूद है?” जांचता है और फिर इन्सर्ट करता है, तो दोनों रिक्वेस्ट चेक पास कर सकती हैं इससे पहले कि कोई भी इन्सर्ट हो।
क्लाइंट, नेटवर्क, और सर्वर को अलग-अलग स्रोत मानें जो दोहराव पैदा कर सकते हैं। आपको तीनों पर सुरक्षा लगाने की ज़रूरत होगी।
अगर आप एक भरोसेमंद जगह चाहते हैं जहां से डुप्लिकेट रोके जाएँ, तो नियम डेटाबेस में रखें। UI फिक्स और सर्वर चेक मदद करते हैं, पर वे रिट्राईज़, लैग, या दो यूज़र्स एक साथ होने पर फेल हो सकते हैं। डेटाबेस यूनिक कॉन्स्ट्रेंट अंतिम अधिकार देता है।
सबसे पहले एक वास्तविक-विश्व यूनिकनेस नियम चुनें जो लोगों की सोच से मेल खाता हो। सामान्य उदाहरण:
ऐसे फ़ील्ड्स के साथ सावधान रहें जो दिखने में यूनिक लगते हैं पर नहीं हैं, जैसे पूरा नाम।
एक बार जब आपके पास नियम हो, तो उसे यूनिक कॉन्स्ट्रेंट (या यूनिक इंडेक्स) से लागू करें। यह डेटाबेस को किसी दूसरे इन्सर्ट को अस्वीकार करने देता है जो नियम का उल्लंघन करता हो, भले ही दो रिक्वेस्ट एक ही समय पर आएं।
जब कॉन्स्ट्रेंट ट्रिगर हो, तो तय करें कि यूज़र को क्या दिखाना चाहिए। अगर डुप्लिकेट बनना हमेशा गलत है, तो इसे एक स्पष्ट संदेश के साथ ब्लॉक करें (“वह ईमेल पहले से उपयोग में है”)। अगर रिट्राईज़ सामान्य हैं और रिकॉर्ड पहले से मौजूद है, तो अक्सर बेहतर होता है कि रिट्राई को सफल समझकर पहले वाला रिकॉर्ड लौटाया जाए (“आपका ऑर्डर पहले ही बन चुका है”)।
अगर आपका create असल में “create या reuse” है, तो upsert सबसे साफ पैटर्न हो सकता है। उदाहरण: “ईमेल से ग्राहक बनाना” एक नई पंक्ति डाल सकता है या मौजूद वाली लौटा सकता है। इसे तभी इस्तेमाल करें जब यह बिजनेस मीनिंग से मेल खाता हो। अगर थोड़ा अलग payloads एक ही की के लिए आ सकते हैं, तो तय करें कौन से फील्ड्स अपडेट हो सकते हैं और कौन से अपरिवर्तित रहने चाहिए।
यूनिक कॉन्स्ट्रेंट्स idempotency कीज़ या अच्छे UI स्टेट्स की जगह नहीं लेतीं, पर वे एक कड़ा रोका देता है जिस पर बाकी सब निर्भर कर सकते हैं।
एक idempotency की एक यूनिक टोकन है जो एक यूज़र इरादे को दर्शाती है, जैसे “इस ऑर्डर को एक बार बनाओ।” अगर वही रिक्वेस्ट फिर से भेजी जाती है (डबल क्लिक, नेटवर्क रिट्राई, मोबाइल रेज़्यूम), तो सर्वर उसे एक रिट्राई समझकर नए क्रिएट के बजाय वही परिणाम देता है।
यह उन create एंडपॉइंट्स के लिए सबसे व्यावहारिक टूल्स में से एक है जहाँ क्लाइंट यह नहीं बता पाता कि पहली कोशिश सफल हुई या नहीं।
जिन एंडपॉइंट्स से सबसे ज़्यादा लाभ होता है वे हैं वे जिनमें डुप्लिकेट महंगा या भ्रम पैदा करने वाला हो—जैसे ऑर्डर, इनवॉइस, पेमेंट्स, इनवाइट्स, सब्सक्रिप्शन, और वो फ़ॉर्म जो ईमेल या वेबहुक ट्रिगर करते हैं।
रिट्राई पर, सर्वर को पहले सफल प्रयास के मूल परिणाम को वापस करना चाहिए, जिसमें वही क्रिएटेड रिकॉर्ड ID और स्टेटस कोड शामिल हों। इसके लिए एक छोटा idempotency रिकॉर्ड स्टोर करें जिसे (यूज़र या अकाउंट) + एंडपॉइंट + idempotency की से की किया जाए। नतीजा (रिकॉर्ड ID, रेस्पॉन्स बॉडी) और एक “प्रोग्रेस में” स्टेट भी सहेजें ताकि दो लगभग समान समय वाली रिक्वेस्ट दोनों रिकॉर्ड न बना दें।
idempotency रिकॉर्ड को उतना ही समय तक रखें जितना असली रिट्राईज़ के लिए जरूरी हो। एक सामान्य बेसलाइन 24 घंटे है। पेमेंट्स के लिए कई टीमें 48–72 घंटे रखती हैं। एक TTL स्टोरेज को सीमित रखता है और उस समय सीमा से मेल खाता है जब तक रिट्राई होने की संभावना है।
अगर आप APIs को किसी चैट-ड्रिवन बिल्डर जैसे Koder.ai से जनरेट करते हैं, तब भी idempotency को स्पष्ट रखें: क्लाइंट-भेजी की स्वीकार करें (हेडर या फील्ड) और सर्वर पर “same key, same result” लागू करें।
Idempotency create रिक्वेस्ट को दोहराने पर भी सुरक्षित बनाती है। अगर क्लाइंट टाइमआउट के कारण रिट्राई करता है (या यूज़र दो बार क्लिक करता है), तो सर्वर वही परिणाम लौटाता है बजाय कि दूसरी पंक्ति बनाए।
Idempotency-Key), पर JSON बॉडी में भेजना भी काम कर सकता है।मुख्य बात यह है कि “चेक + स्टोर” कॉन्करेंसी के तहत सुरक्षित होना चाहिए। व्यवहार में, आप idempotency रिकॉर्ड को (scope, key) पर यूनिक कॉन्स्ट्रेंट के साथ स्टोर करते हैं और कॉन्फ्लिक्ट्स को पुन: उपयोग का सिग्नल मानते हैं।
if idempotency_record exists for (user_id, key):
return saved_response
else:
begin transaction
create the row
save response under (user_id, key)
commit
return response
उदाहरण: एक ग्राहक “Create invoice” करता है, ऐप की भेजता है abc123, और सर्वर invoice inv_1007 बनाता है। अगर फोन सिग्नल खो दे और रिट्राई हो, तो सर्वर वही inv_1007 रेस्पॉन्स देगा, न कि inv_1008।
जब आप टेस्ट करें, तो सिर्फ़ “डबल क्लिक” पर न रुकें। एक ऐसी रिक्वेस्ट का सिमुलेशन करें जो क्लाइंट पर टाइमआउट हो जाए पर सर्वर पर पूरी हो जाए, फिर उसी की के साथ रिट्राई करें।
सर्वर-साइड रक्षा मायने रखती है, पर कई डुप्लिकेट फिर भी इंसान के सामान्य रूप से दो बार करने से शुरू होते हैं। अच्छा UI सुरक्षित रास्ता स्पष्ट बनाता है।
सबमिट होते ही सबमिट बटन डिसेबल कर दें। यह पहले क्लिक पर करें, न कि वैलिडेशन के बाद या रिक्वेस्ट शुरू होने पर। अगर फॉर्म कई कंट्रोल्स से सबमिट हो सकता है (एक बटन और Enter), तो पूरे फॉर्म स्थिति को लॉक करें, केवल एक बटन नहीं।
एक स्पष्ट प्रोग्रेस स्टेट दिखाएँ जो एक सवाल का जवाब दे: क्या यह काम कर रहा है? एक साधारण “Saving...” लेबल या स्पिनर काफी है। लेआउट स्थिर रखें ताकि बटन न हिले और दूसरा क्लिक न आकर्षित करे।
एक छोटा नियम सेट अधिकांश डबल सबमिट रोक देता है: सबमिट हैंडलर की शुरुआत में एक isSubmitting फ्लैग सेट करें, जब यह true हो तब नए सबमिट को इग्नोर करें (क्लिक और Enter दोनों के लिए), और असली रेस्पॉन्स मिलने तक इसे क्लियर न करें।
धीरे-धीरे आने वाले रेस्पॉन्स वही जगह है जहाँ कई ऐप्स फिसलते हैं। यदि आप बटन को एक तय टाइमर (उदा. 2 सेकंड) के बाद फिर से सक्रिय कर देते हैं, तो यूज़र पहले रिक्वेस्ट के चलते हुए भी फिर से सबमिट कर सकते हैं। केवल तभी रिइनेबल करें जब प्रयास पूरा हो चुका हो।
सफलता के बाद, फिर से सबमिशन को मुश्किल बनाएं। नेविगेट कर दें (नए रिकॉर्ड पेज या लिस्ट पर) या एक स्पष्ट सक्सेस स्टेट दिखाएँ जिसमें बनाया गया रिकॉर्ड दिखाई दे। उसी भरे हुए फॉर्म को स्क्रीन पर छोड़ कर बटन सक्रिय रखना टालें।
सबसे जिद्दी डुप्लिकेट बग रोज़मर्रा की “अजीब पर सामान्य” बिहेवियर से आते हैं: दो टैब, एक रिफ्रेश, या फोन का सिग्नल खो देना।
सबसे पहले, यूनिकनेस को सही स्कोप दें। “यूनिक” शायद ही कभी “सभी डेटाबेस में यूनिक” का मतलब होता है। यह हो सकता है प्रति यूज़र, प्रति वर्कस्पेस, या प्रति टेनेंट। अगर आप किसी बाहरी सिस्टम के साथ सिंक करते हैं, तो आपको बाहरी स्रोत और उसका external ID के लिए यूनिकनेस चाहिए हो सकती है। एक सुरक्षित तरीका यह है कि आप वह वाक्य लिख कर रखें जो आप सच में मतलब रखते हैं (उदाहरण: “प्रति टेनेंट प्रति वर्ष एक इनवॉइस नंबर”), फिर उसे लागू करें।
मल्टी-टैब बिहेवियर क्लासिक ट्रैप है। UI लोडिंग स्टेट एक टैब में मदद करते हैं, पर वे टैब्स के बीच कुछ नहीं करते। यहाँ सर्वर-साइड रक्षा का काम करना ज़रूरी है।
बैक बटन और रिफ्रेश आकस्मिक रिसबमिट ट्रिगर कर सकते हैं। सफल क्रिएट के बाद यूज़र अक्सर चेक करने के लिए रिफ्रेश कर देते हैं, या Back दबाकर वही फॉर्म फिर से सबमिट कर देते हैं। मूल फॉर्म की बजाय एक क्रिएटेड व्यू दिखाना बेहतर है, और सर्वर को सुरक्षित रीप्ले संभालना चाहिए।
मोबाइल में बाधाएँ आती हैं: बैकग्राउंडिंग, फ्लेकी नेटवर्क, और ऑटोमैटिक रिट्राईज़। एक रिक्वेस्ट सफल हो सकती है, पर ऐप कभी रिस्पॉन्स न पाने के कारण रेज़्यूम पर फिर से ट्राय कर दे।
सर्वाधिक सामान्य फेल्योर मोड यह है कि UI को ही एकमात्र गार्डरेल माना जाए। एक डिसेबल बटन और स्पिनर मदद करते हैं, पर वे रिफ्रेश, फ्लेकी मोबाइल नेटवर्क, दो टैब, या क्लाइंट बग को कवर नहीं करते। सर्वर और डेटाबेस को फिर भी यह कहने में सक्षम होना चाहिए कि “यह क्रिएट पहले ही हो चुका है।”
एक और जाल गलत फ़ील्ड पर यूनिक कॉन्स्ट्रेंट चुनना है। अगर आप किसी ऐसे फ़ील्ड पर यूनिक कॉन्स्ट्रेंट लगा दें जो सचमुच यूनिक नहीं है (जैसे सरनेम, राउंड किया हुआ टाइमस्टैम्प, फ्री-फॉर्म टाइटल), तो आप वैध रिकॉर्ड्स को ब्लॉक कर देंगे। इसके बजाय एक असली पहचानकर्ता का उपयोग करें (जैसे बाहरी प्रोवाइडर ID) या स्कोप्ड नियम (प्रति यूज़र, प्रति दिन, या प्रति पैरेंट रिकॉर्ड)।
Idempotency कीज़ भी गलत तरीके से लागू करना आसान है। अगर क्लाइंट हर रिट्राई पर नई की जनरेट कर दे, तो हर बार नया क्रिएट होगा। उसी इरादे के लिए पहली क्लिक से लेकर किसी भी रिट्राई तक की को ही स्थिर रखें।
यह भी देखें कि आप रिट्राई पर क्या वापस कर रहे हैं। अगर पहली रिक्वेस्ट ने रिकॉर्ड बनाया था, तो रिट्राई को वही परिणाम (कम से कम वही रिकॉर्ड ID) लौटाना चाहिए, न कि एक अस्पष्ट त्रुटि जो यूज़र को फिर से कोशिश करने पर मजबूर करे।
अगर यूनिक कॉन्स्ट्रेंट किसी डुप्लिकेट को ब्लॉक कर देता है, तो इसे “Something went wrong” के पीछे छिपाएँ नहीं। साफ़ भाषा में बताइए: “यह इनवॉइस नंबर पहले से मौजूद है। हमने मूल रखा और दूसरा नहीं बनाया।”
रिलीज़ से पहले, खासकर डुप्लिकेट क्रिएशन पाथ्स के लिए एक त्वरित पास कर लें। सबसे अच्छे नतीजे तब मिलते हैं जब आप कई परतों वाली रक्षा लागू करते हैं ताकि एक छूटी हुई क्लिक, रिट्राई, या धीमा नेटवर्क दो पंक्तियाँ न बना सके।
इन तीन बातों की पुष्टि करें:
एक व्यावहारिक गट चेक: फॉर्म खोलें, तेजी से दो बार सबमिट करें, फिर बीच में रिफ्रेश कर के फिर कोशिश करें। अगर आप दो रिकॉर्ड बना पाते हैं, तो असली यूज़र्स भी करेंगे।
एक छोटा इनवॉयसिंग ऐप कल्पना करें। एक यूज़र नया इनवॉइस भरता है और Create टैप करता है। नेटवर्क धीमा है, स्क्रीन तुरंत नहीं बदलती, और वे फिर से Create टैप कर देते हैं।
सिर्फ UI सुरक्षा के साथ, आप बटन डिसेबल कर स्पिनर दिखा सकते हैं। वह मदद करता है, पर पर्याप्त नहीं होता। कुछ डिवाइस पर डबल टैप अभी भी फिसल सकता है, टाइमआउट के बाद रिट्राई हो सकता है, या यूज़र दो टैब से सबमिट कर सकता है।
सिर्फ डेटाबेस यूनिक कॉन्स्ट्रेंट के साथ, आप सटीक डुप्लिकेट रोक पाएँगे, पर एक्सपीरियंस कच्चा हो सकता है। पहली रिक्वेस्ट सफल हुई, दूसरी कॉन्स्ट्रेंट से फँस जाएगी, और यूज़र को एक त्रुटि दिखेगी भले ही इनवॉइस बन गया हो।
साफ़ परिणाम idempotency प्लस यूनिक कॉन्स्ट्रेंट है:
दूसरे टैप के बाद एक साधारण UI संदेश: “Invoice created - हमने डुप्लिकेट सबमिशन को अनदेखा किया और आपकी पहली रिक्वेस्ट को रखा।”
एक बार बुनियादी चीजें सेट हो जाने पर, अगली जीतें विजिबिलिटी, क्लीनअप, और एकरूपता के बारे में हैं।
क्रिएट पाथ्स के चारों ओर हल्का-फुल्का लॉगिंग जोड़ें ताकि आप असली यूज़र एक्शन और रिट्राईज़ में फर्क कर सकें। idempotency की, शामिल यूनिक फ़ील्ड्स, और परिणाम (created vs returned existing vs rejected) लॉग करें। शुरू करने के लिए भारी टूलिंग की ज़रूरत नहीं है।
अगर पहले से डुप्लिकेट मौजूद हैं, तो उन्हें साफ़ करने के लिए एक स्पष्ट नियम और ऑडिट ट्रेल बनाइए। उदाहरण के लिए, सबसे पुराना रिकॉर्ड “विजेता” रखें, संबंधित रो (payments, line items) को री-ऐटैच करें, और बाकी को merged के रूप में मार्क करें बजाय डिलीट करने के। इससे सपोर्ट और रिपोर्टिंग आसान होती है।
अपनी यूनिकनेस और idempotency नियम एक जगह लिख कर रखें: क्या यूनिक है और किस स्कोप में, idempotency कीज़ कितनी देर रहती हैं, एरर कैसा दिखेगा, और UI रिट्राई पर क्या करे। इससे नए एंडपॉइंट्स अनजाने में सेफ्टी रेल्स को बाईपास नहीं करेंगे।
यदि आप CRUD स्क्रीन जल्दी बना रहे हैं Koder.ai (koder.ai) में, तो इन व्यवहारों को अपनी डिफ़ॉल्ट टेम्पलेट का हिस्सा बनाना फायदेमंद है: स्कीमा में यूनिक कॉन्स्ट्रेंट्स, API में idempotent create एंडपॉइंट्स, और UI में स्पष्ट लोडिंग स्टेट्स। इस तरह, स्पीड का मतलब गंदे डेटा नहीं होगा।
डुप्लिकेट रिकॉर्ड तब होते हैं जब वही वास्तविक चीज़ दो बार स्टोर हो जाती है—जैसे एक चेकआउट के लिए दो ऑर्डर या एक ही समस्या के लिए दो टिकट। यह अक्सर तब होता है जब एक ही “create” क्रिया दो बार चल जाती है, यूज़र के डबल सबमिट, रिट्राई या समकक्ष अनुरोधों की वजह से।
किसी यूज़र ने एक बार क्लिक किया भी हो तो भी दूसरा create ट्रिगर हो सकता है—मोबाइल पर डबल टैप, Enter दबाना और फिर बटन क्लिक करना, या क्लाइंट/नेटवर्क/सर्वर द्वारा रिट्राई। सर्वर यह मानकर नहीं चल सकता कि POST का अर्थ हमेशा एक बार ही निष्पादन है।
नहीं—यह भरोसेमंद तरीका नहीं है। सबमिट बटन डिसेबल करना और “Saving…” दिखाना आकस्मिक डबल सबमिट घटा देता है, पर यह फ्लेकी नेटवर्क, रिफ्रेश, मल्टी-टैब, बैकग्राउंड वर्कर्स या वेबहुक रेडिलिवरीज़ को रोकता नहीं। सर्वर और डेटाबेस स्तर पर भी सुरक्षा चाहिए।
डेटाबेस यूनिक कॉन्स्ट्रेंट्स आखिरी लाइन ऑफ़ डिफेंस हैं—यह दो एक जैसी पंक्तियाँ जोड़ने से रोकते हैं भले ही दो अनुरोध एक साथ आएं। इन्हें ऐसे फ़ील्ड पर लगाएँ जो वास्तविक दुनिया की यूनिकनेस को दर्शाते हों, और अक्सर इन्हें स्कोप किया जाता है (जैसे प्रति टेनेंट)।
दोनों की ज़रूरत होती है। यूनिक कॉन्स्ट्रेंट्स फिल्ड-आधारित डुप्लिकेट को रोकते हैं (जैसे इनवॉइस नंबर), जबकि idempotency कीज़ एक खास क्रिएट-attempt को सुरक्षित बनाती हैं ताकि वही की दोबारा भेजने पर वही नतीजा लौटे। दोनों मिलकर सुरक्षा और बेहतर UX देते हैं।
प्रत्येक यूज़र इरादे (उदाहरण: “Create” दबाने पर) के लिए एक की बनाइए, उसी इरादे के सभी रिट्राईज़ में वही की दुबारा भेजिए। की समय-सीमा तक स्थिर रहनी चाहिए और अलग क्रिएट के लिए पुन: उपयोग नहीं होनी चाहिए।
सर्वर एक idempotency रिकॉर्ड स्टोर करे जो स्कोप (यूज़र या अकाउंट), एंडपॉइंट और idempotency की पर आधारित हो और पहले सफल अनुरोध के लिए जो रेस्पॉन्स लौटा था उसे सहेजे। वही की फिर आने पर वही सहेजा रेस्पॉन्स (और वही रिकॉर्ड ID) लौटाएं, नया रिकॉर्ड न बनाएं।
‘चेक + स्टोर’ को concurrency-सुरक्षित बनाइए: idempotency रिकॉर्ड पर भी यूनिक कॉन्स्ट्रेंट रखें (स्कोप + की)। इससे एक ही समय पर दो अनुरोध दोनों “पहले” साबित नहीं हो सकेंगे, और एक को स्टोर किया हुआ नतीजा पुन: उपयोग करने के लिए मजबूर किया जाएगा।
रियलिस्टिक रिट्राई कवर करने के लिए पर्याप्त समय तक रखें; सामान्यत: 24 घंटे एक बेसलाइन है, पेमेंट जैसी चीज़ों के लिए 48–72 घंटे रखना सामान्य है। एक TTL रखें ताकि स्टोरेज अनियंत्रित न बढ़े।
जब वही इरादा स्पष्ट हो (यानी यही रीक्वेस्ट है), तब उसे सफल रिट्राई समझें और वही मूल रिकॉर्ड (सही ID) लौटाएँ। यदि रिकॉर्ड सचमुच यूनिक होना चाहिए और दूसरी कोशिश अलग है, तो स्पष्ट कॉन्फ्लिक्ट संदेश दें—उदाहरण: “यह इनवॉइस नंबर पहले से मौजूद है, हमने मूल रखा।”