SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

n8n schedule trigger गलत समय पर क्यों चलता है

n8n schedule trigger के गलत समय पर चलने का कारण तीन अलग-अलग timezone सेटिंग्स हैं। सही परिणाम पाने के लिए TZ, GENERIC_TIMEZONE और workflow timezone को एक साथ कॉन्फ़िगर करना सीखें।

आपका n8n schedule trigger गलत समय पर क्यों चलता है

n8n schedule trigger गलत समय पर इसलिए चलता है क्योंकि n8n तीन अलग-अलग जगहों से अपना timezone पढ़ता है, और उनमें से किसी एक को ठीक करने से समस्या का केवल एक हिस्सा ही हल होता है। ये तीन जगहें हैं: container का अपना TZ variable, instance का default GENERIC_TIMEZONE, और किसी विशिष्ट workflow के भीतर सेट किया गया timezone। इन तीनों को एक बार सेट कर लें, तो उसके बाद आप जो भी schedule बनाएंगे, वह आपकी उम्मीद के अनुसार ही काम करेगा।

सबसे पहले एक गलत धारणा को सुधारें। एक नया self-hosted n8n, UTC (coordinated universal time) में schedule नहीं करता है। Container की clock UTC में होती है, क्योंकि official image में कोई TZ सेट नहीं होता है। Scheduling एक अलग परत है, और GENERIC_TIMEZONE के लिए n8n का documented default America/New_York है (अगस्त 2026 तक), इसलिए एक untouched instance अपने Schedule Triggers को New York के समय पर चलाता है। यही कारण है कि लोग जो offset बताते हैं, वह शायद ही कभी UTC से उनकी अपनी दूरी से मेल खाता है। Berlin का एक owner जो 06:00 का समय मांगता है, उसे local समय के अनुसार 12:00 बजे का परिणाम मिलता है, और मार्च के उन हफ्तों के दौरान 11:00 बजे का, जब United States daylight saving time में चला जाता है लेकिन Europe नहीं गया होता।

तीन timezone लेयर्स, और कौन सी प्रभावी होती है

TZ कंटेनर के अंदर ऑपरेटिंग सिस्टम का timezone है। n8n documentation इसे उस variable के रूप में वर्णित करता है जो सिस्टम timezone को सेट करता है, ताकि यह नियंत्रित किया जा सके कि date जैसे scripts और commands क्या परिणाम देते हैं। यह तय करता है कि कंटेनर के अंदर date क्या प्रिंट करेगा, कंटेनर लॉग लाइन पर क्या timestamp दर्ज होगा, Code node में new Date() क्या परिणाम देगा, और वहां चलने वाली कोई भी shell script क्या देखेगी। Schedule Trigger कब फायर होगा, इस पर इसका कोई प्रभाव नहीं पड़ता है।

GENERIC_TIMEZONE n8n instance का timezone है। Documentation इसे n8n instance timezone कहती है और बताती है कि यह Cron जैसे schedule nodes के लिए महत्वपूर्ण है। यहाँ Cron का अर्थ मानक समय-आधारित शेड्यूलिंग सिंटैक्स है, और n8n इसे Schedule Trigger पर Custom (Cron) विकल्प के रूप में प्रदान करता है।

Workflow timezone को प्रत्येक workflow के लिए अलग से सेट किया जाता है। Canvas पर workflow खोलें, ऊपरी दाएं कोने में तीन बिंदुओं को चुनें, Settings चुनें, और फिर Timezone मान बदलें। यह उस एक विशिष्ट workflow के लिए GENERIC_TIMEZONE को ओवरराइड कर देता है।

Schedule Trigger के लिए क्रम निश्चित है। यदि workflow में timezone सेट है तो n8n उसका उपयोग करता है, अन्यथा GENERIC_TIMEZONE से instance timezone का उपयोग करता है, और यदि वह भी न हो तो अपने इन-बिल्ट डिफ़ॉल्ट America/New_York का उपयोग करता है। उस निर्णय के किसी भी चरण में TZ को नहीं देखा जाता है।

आपके nodes के अंदर तारीखों के लिए, उत्तर इस बात पर निर्भर करता है कि कोड किस घड़ी से पूछता है। n8n expressions के पीछे की date library, Luxon, n8n timezone का उपयोग करती है, इसलिए $now और $today उसी workflow-फिर-instance के क्रम का पालन करते हैं जैसा कि trigger करता है। Code node में साधारण JavaScript new Date() ऑपरेटिंग सिस्टम से पूछता है, इसलिए यह TZ का पालन करता है। यह विभाजन ही यहाँ अधिकांश भ्रम का स्रोत है: trigger सही हो सकता है जबकि workflow द्वारा लिखा गया हर timestamp घंटों आगे या पीछे हो सकता है।

Compose file में तीनों को सेट करें

फाइल में TZ और GENERIC_TIMEZONE को एक-दूसरे के बगल में रखें ताकि कोई एक को सेट करके दूसरे को भूल न जाए। नीचे दिया गया अंश एक कार्यशील सर्विस का timezone-संबंधित हिस्सा है। फाइल का बाकी हिस्सा, reverse proxy और certificate, HTTPS के पीछे VPS पर self-hosted n8n से आता है।

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - GENERIC_TIMEZONE=Europe/Berlin
      - TZ=Europe/Berlin
      - N8N_RUNNERS_ENABLED=true
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

इसे docker compose up -d के साथ लागू करें, न कि docker compose restart के साथ। एक restart उसी container को उसी environment के साथ फिर से शुरू करता है जिसके साथ वह बनाया गया था, इसलिए फाइल में किए गए बदलाव और चल रही प्रक्रिया में कोई अंतर नहीं आता। up -d बदले हुए environment को देखता है और container को फिर से बनाता है। यदि आप इन values को inline के बजाय env file में रखते हैं, तो भी वही recreate नियम लागू होता है, और Compose env file और secrets handling गाइड में बताया गया है कि वह फाइल कहाँ से पढ़ी जाती है।

Region/City फॉर्मेट में IANA (Internet Assigned Numbers Authority) zone नाम का उपयोग करें, जैसे कि Europe/Berlin या America/Sao_Paulo। उन नामों में उस स्थान के लिए daylight saving नियम शामिल होते हैं, इसलिए जब स्थानीय घड़ियाँ बदलती हैं तो offset भी बदल जाता है। Etc/GMT+5 जैसा fixed-offset नाम मौसम के साथ कभी नहीं बदलता है, और इसका sign आपके अनुमान से उल्टा होता है। LC_ALL=C TZ=Etc/GMT+5 date +%z चलाएं और यह -0500 प्रिंट करेगा। उन नामों से बचें।

केवल एक को सेट करने से समस्या पूरी तरह हल क्यों नहीं होती

केवल GENERIC_TIMEZONE को सेट करने पर Schedule Trigger आपके द्वारा निर्धारित घंटे पर चलता है, जबकि ऑपरेटिंग सिस्टम को पढ़ने वाली अन्य सभी चीजें UTC पर ही रहती हैं। new Date().toString() को कॉल करने वाला Code node एक UTC स्ट्रिंग लौटाता है, कंटेनर लॉग लाइन्स पर UTC समय अंकित होता है, और सिस्टम क्लॉक से बनी कोई भी फाइल का नाम गलत मध्यरात्रि (midnight) पर बदल जाता है।

केवल TZ को सेट करने पर इसका उल्टा होता है। docker compose exec n8n date आपका स्थानीय समय दिखाता है, जो सही लगता है, जबकि Schedule Trigger अभी भी America/New_York पर है और आपके द्वारा मांगे गए घंटे से छह घंटे बाद चलता है। यह वह स्थिति है जिसमें सबसे अधिक समय बर्बाद होता है, क्योंकि अधिकांश लोग सबसे पहले जिस जांच को चलाते हैं, वह अब सफल हो जाती है।

यदि आप एक workflow timezone सेट करते हैं और बाद में GENERIC_TIMEZONE को बदलते हैं, तो वह workflow इस बदलाव को अनदेखा कर देता है। workflow का मान प्रभावी रहता है, और यह तब तक प्रभावी रहता है जब तक कोई उस workflow की सेटिंग्स को खोलता नहीं है। यदि कोई workflow अजीब समय पर चल रहा है जबकि उसके पड़ोसी workflow ठीक चल रहे हैं, तो इसका कारण लगभग हमेशा यही होता है।

अनुमान लगाने के बजाय घड़ियों की जाँच करें

Host और container की समय-सीमा की सीधे तुलना करें।

date
docker compose exec n8n date
docker compose exec n8n printenv TZ GENERIC_TIMEZONE

जब TZ सेट हो जाए, तो पहली दो commands को एक ही wall-clock time दिखाना चाहिए। printenv प्रत्येक मौजूद variable के लिए एक लाइन प्रिंट करता है, इसलिए दो लाइन का आउटपुट यह दर्शाता है कि दोनों सेट हैं, और एक लाइन का मतलब है कि आप आधी-अधूरी स्थिति देख रहे हैं।

अब n8n से ही पूछें, एक workflow के अंदर से, क्योंकि container shell आपको यह नहीं बता सकता कि workflow-level timezone क्या है। उस workflow में एक Code node जोड़ें जो ठीक से काम नहीं कर रहा है और उसे Execute Workflow के साथ एक बार चलाएं।

return [
  {
    json: {
      n8n_time: $now.toISO(),
      n8n_zone: $now.zoneName,
      system_time: new Date().toString(),
    },
  },
];

n8n_zone वह zone है जिसका उपयोग इस workflow का Schedule Trigger करेगा, जो पहले से ही workflow-then-instance क्रम के माध्यम से हल हो चुका है, इसलिए यह सीधे सवाल का जवाब देता है। system_time, TZ से container का अपना zone ले जाता है। इसे उस workflow में चलाएं जो ठीक से काम नहीं कर रहा है, न कि किसी नए में, क्योंकि workflow-level सेटिंग workflow के साथ ही चलती है। यदि वे दो मान अलग-अलग हैं, तो आपने बिना कोई config file खोले ही समस्या का पता लगा लिया है।

Schedule Trigger node में Cron expressions

Schedule Trigger सेकंड से लेकर महीनों तक के निश्चित अंतराल प्रदान करता है, और जो अंतराल इनमें कवर नहीं होते उनके लिए Custom (Cron) का विकल्प उपलब्ध है। Cron expression को workflow के resolved timezone के अनुसार पढ़ा जाता है, इसलिए 0 6 * * * का अर्थ उस zone में 06:00 है, न कि 06:00 UTC। crontab guru से पाँच-फील्ड वाला expression जैसा है वैसा ही paste किया जा सकता है। n8n एक वैकल्पिक seconds फील्ड भी स्वीकार करता है, जिसे documentation की फील्ड टेबल में सबसे पहले रखा गया है: second, minute, hour, day of month, month, day of week।

Offset को कभी भी मैन्युअल रूप से encode न करें। Berlin में 06:00 का समय पाने के लिए UTC instance पर 0 4 * * * लिखना सर्दियों में सही है, लेकिन गर्मियों में यह एक घंटे का अंतर पैदा कर देगा, क्योंकि Berlin सर्दियों में UTC+1 और गर्मियों में UTC+2 पर चलता है। सही zone सेट करें और वह local hour लिखें जिसका आप वास्तव में उपयोग करना चाहते हैं।

Daylight saving का 02:30 पर सेट किए गए जॉब पर प्रभाव

स्थानीय wall-clock समय एक निश्चित क्षण की गारंटी नहीं देता है। साल में दो बार एक घंटा गायब हो जाता है और एक घंटा दोहराया जाता है, और उन घंटों के बीच निर्धारित कोई भी जॉब प्रभावित होता है। आप इसे किसी भी Linux बॉक्स पर date के साथ देख सकते हैं, जिसमें n8n शामिल नहीं है।

LC_ALL=C TZ=Europe/Berlin date -d '2027-03-28 02:30'
date: invalid date '2027-03-28 02:30'

कमांड में यह कोई टाइपो नहीं है। 2027-03-28 को बर्लिन की घड़ी सीधे 02:00 से 03:00 पर चली जाती है, इसलिए उस दिन स्थानीय 02:30 का समय अस्तित्व में ही नहीं होता, और date इसे एक क्षण में बदलने से इनकार कर देता है। 02:30 स्थानीय समय पर निर्धारित जॉब के चलने का कोई समय नहीं होता। पड़ोसी समय ठीक काम करते हैं: date -d '2027-03-28 01:30' का समाधान CET के रूप में होता है और date -d '2027-03-28 03:30' का समाधान CEST के रूप में होता है।

पतझड़ का बदलाव इसका दर्पण प्रतिबिंब है। 2027-10-31 को बर्लिन की घड़ी 03:00 से वापस 02:00 पर आ जाती है, इसलिए 02:30 का समय दो बार आता है।

LC_ALL=C TZ=Europe/Berlin date -d '2027-10-31 02:30 CEST' '+%s'
LC_ALL=C TZ=Europe/Berlin date -d '2027-10-31 02:30 CET' '+%s'
1824942600
1824946200

दो अलग-अलग क्षण, दोनों को स्थानीय 02:30 कहा जाता है, जिनके बीच 3600 सेकंड का अंतर होता है। वहां पिन किया गया जॉब या तो दो बार चलता है या ऐसे समय पर चलता है जिसे किसी ने नहीं चुना था, और इनमें से कोई भी परिणाम billing run या backup rotation के लिए उपयुक्त नहीं है। शेड्यूल को उस विंडो से बाहर ले जाएं। अधिकांश यूरोपीय और उत्तरी अमेरिकी ज़ोन में जोखिम भरा समय स्थानीय 00:00 से 03:00 के बीच होता है।

Infrastructure को UTC में शेड्यूल करें और लोगों को स्थानीय समय दिखाएं

मानक उत्तर उस काम को अलग करता है जो एक timezone करता है। मशीनों को एक स्थिर अंतराल की आवश्यकता होती है। लोगों को पढ़ने योग्य घंटे की आवश्यकता होती है।

  • ऐसे काम के लिए जिसे कोई नहीं देखता, workflow timezone को UTC पर सेट करें। बैकअप, कैश वार्मिंग, लॉग शिपिंग और रिपोर्ट जनरेशन इसी श्रेणी में आते हैं। UTC में दो रन के बीच का अंतर साल के हर दिन बिल्कुल वही होता है जो आपने लिखा है, क्योंकि UTC में daylight saving नहीं होती है।
  • ऐसे काम के लिए जिसे कोई व्यक्ति पढ़ता है, शेड्यूल को UTC में रखें और प्रदर्शन के समय उसे बदलें। एक expression यह काम करता है: {{ $now.setZone('Europe/Berlin').toFormat('yyyy-MM-dd HH:mm') }} संदेश बॉडी में स्थानीय समय डालता है जबकि ट्रिगर स्थिर रहता है।

यही विभाजन n8n के बाहर भी लागू होता है। जब आपकी automation का एक हिस्सा VPS पर एक systemd service और timer के रूप में चलता है, तो उसकी OnCalendar लाइन को system timezone में पढ़ा जाता है, जो अपनी सेटिंग वाली चौथी घड़ी है। हर scheduler को UTC पर रखने से आपको चार के बजाय केवल एक नियम याद रखना पड़ता है। यह किसी भी ऐसी चीज़ के लिए भी मायने रखता है जो एक अवधि का सारांश देती है, क्योंकि एक n8n AI agent workflow जिससे कल के आंकड़े मांगे गए हैं, वह चुपचाप अलग-अलग 24 घंटों का उपयोग करेगा, यह इस पर निर्भर करता है कि कौन सा ज़ोन रिज़ॉल्व हुआ है।

विफलता के प्रकार और आपको दिखाई देने वाला आउटपुट

सब कुछ छह घंटे की देरी से चलता है। GENERIC_TIMEZONE कभी सेट नहीं किया गया था, इसलिए इन-बिल्ट डिफ़ॉल्ट America/New_York लागू होता है। docker compose exec n8n printenv GENERIC_TIMEZONE कुछ भी प्रिंट नहीं करता है। इसे सेट करें, फिर कंटेनर को फिर से बनाएँ।

आपने Compose फ़ाइल को एडिट किया और कुछ भी नहीं बदला। आपने docker compose restart चलाया, इसलिए कंटेनर ने अपना मूल वातावरण बनाए रखा। docker compose up -d चलाएँ, फिर docker compose exec n8n printenv TZ के साथ पुष्टि करें।

ट्रिगर सही है और टाइमस्टैम्प गलत हैं। केवल GENERIC_TIMEZONE सेट है। Code नोड में new Date() अभी भी ऑपरेटिंग सिस्टम से UTC पढ़ता है। TZ को उसी मान पर सेट करें और फिर से बनाएँ।

एक वर्कफ़्लो इंस्टेंस सेटिंग को अनदेखा करता है। उस वर्कफ़्लो की अपनी सेटिंग्स में अपना टाइमज़ोन होता है, जो GENERIC_TIMEZONE पर प्राथमिकता लेता है। कैनवास खोलें, तीन बिंदुओं पर क्लिक करें, सेटिंग्स में जाएँ, और टाइमज़ोन चुनें।

एक दैनिक जॉब दो बार चली, या इस वर्ष एक दिन छूट गया। इसका निर्धारित समय डेलाइट सेविंग ट्रांज़िशन के भीतर आता है। समय बदलें, या उस वर्कफ़्लो को UTC पर ले जाएँ।

FAQ

मेरा n8n schedule trigger गलत समय पर क्यों चलता है?

Workflow उस timezone का उपयोग कर रहा है जिसे आप मान रहे हैं, वह उससे अलग है। यदि workflow में कोई timezone सेट है तो n8n उसे चुनता है, अन्यथा यह GENERIC_TIMEZONE से instance timezone लेता है, और यदि वह भी न हो तो America/New_York का अपना डिफ़ॉल्ट उपयोग करता है। एक self-hosted instance जहाँ किसी ने GENERIC_TIMEZONE सेट नहीं किया है, वह UTC के बजाय New York समय पर schedule करता है, यही कारण है कि यह offset शायद ही कभी UTC से आपकी दूरी के अनुरूप होता है। docker compose exec n8n printenv GENERIC_TIMEZONE चलाएं। यदि कोई output नहीं आता है, तो इसका मतलब है कि इसे कभी सेट नहीं किया गया था।

n8n में TZ और GENERIC_TIMEZONE के बीच क्या अंतर है?

TZ कंटेनर के अंदर का operating system timezone है। यह नियंत्रित करता है कि कंटेनर के अंदर date क्या return करता है, कंटेनर log lines पर क्या timestamps दिखाई देते हैं, Code node में new Date() क्या return करता है, और वहां चलने वाली कोई भी script क्या देखती है। GENERIC_TIMEZONE n8n instance का timezone है, और schedule nodes तथा Luxon expressions जैसे कि $now इसी का उपयोग करते हैं। एक को दूसरे के बिना सेट करने पर आपको सही trigger के साथ गलत timestamps, या सही timestamps के साथ गलत समय पर चलने वाला trigger मिल सकता है। दोनों को एक ही मान पर सेट करें।

क्या मुझे workflow timezone सेट करना चाहिए या GENERIC_TIMEZONE?

पूरे instance के लिए डिफ़ॉल्ट के रूप में GENERIC_TIMEZONE सेट करें, और per-workflow सेटिंग का उपयोग केवल तभी करें जब कोई workflow वास्तव में किसी अन्य zone से संबंधित हो। Workflow का मान instance के मान से अधिक प्रभावी होता है, और यह GENERIC_TIMEZONE में बाद में किए गए बदलावों का पालन नहीं करता है, इसलिए महीनों बाद per-workflow override को ढूंढना मुश्किल होता है।

जब घड़ियों का समय बदलता है तो 02:30 पर scheduled job का क्या होता है?

वह स्थानीय समय या तो गायब हो जाता है या दो बार आता है। LC_ALL=C TZ=Europe/Berlin date -d '2027-03-28 02:30', date: invalid date '2027-03-28 02:30' return करता है, क्योंकि उस दिन Berlin की घड़ी 02:00 से सीधे 03:00 पर पहुँच जाती है। 2027-10-31 को वही wall-clock रीडिंग एक घंटे के अंतराल पर दो अलग-अलग क्षणों को दर्शाती है। Scheduled कार्यों को 00:00 से 03:00 के स्थानीय समय अंतराल से बाहर रखें, या workflow को UTC पर सेट करें और केवल वहां स्थानीय समय में बदलें जहां कोई व्यक्ति इसे पढ़ता है।