SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor

n8n Schedule Trigger غلط وقت پر کیوں چلتا ہے؟

n8n کے schedule trigger میں وقت غلط آنے کی وجہ تین timezone settings ہیں۔ TZ، GENERIC_TIMEZONE اور workflow timezone درست کریں، ورنہ trigger 6 گھنٹے تک آگے چل سکتا ہے۔

آپ کا 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 ایک الگ layer ہے، اور GENERIC_TIMEZONE کے لیے n8n کا دستاویزی default America/New_York ہے (August 2026 تک)۔ اس لیے غیر تبدیل شدہ instance اپنے Schedule Triggers کو New York کے وقت پر چلاتا ہے۔ اسی وجہ سے لوگ جس offset کی اطلاع دیتے ہیں، وہ شاذونادر ہی UTC سے ان کے اپنے مقامی فرق کے مطابق ہوتا ہے۔ Berlin میں موجود owner اگر 06:00 مقرر کرے تو مقامی وقت کے مطابق یہ 12:00 پر چلے گا، اور March کے ان ہفتوں میں 11:00 پر چلے گا جب United States daylight saving time پر منتقل ہو چکا ہو لیکن Europe ابھی منتقل نہ ہوا ہو۔

تین timezone layers، اور ان میں سے کون سی ترجیح پاتی ہے

TZ container کے اندر operating system کا timezone ہے۔ n8n documentation کے مطابق یہ وہ variable ہے جو system timezone مقرر کرتا ہے، تاکہ یہ طے ہو سکے کہ scripts اور date جیسے commands کیا return کریں گے۔ یہ طے کرتا ہے کہ container کے اندر date کیا print کرے گا، container log line پر کون سا timestamp درج ہوگا، Code node میں new Date() کیا return کرے گا، اور وہاں چلائی جانے والی shell script کو کیا timezone نظر آئے گا۔ اس کا Schedule Trigger کے fire ہونے کے وقت پر کوئی اثر نہیں ہوتا۔

GENERIC_TIMEZONE n8n instance کا timezone ہے۔ documentation اسے n8n instance timezone کہتی ہے اور بتاتی ہے کہ یہ Cron جیسے schedule nodes کے لیے اہم ہے۔ یہاں Cron سے مراد time-based scheduling کا standard syntax ہے، اور n8n اسے Schedule Trigger میں Custom (Cron) option کے طور پر فراہم کرتا ہے۔

Workflow timezone ہر workflow کے لیے الگ مقرر ہوتا ہے۔ canvas پر workflow کھولیں، اوپری دائیں کونے میں تین dots منتخب کریں، Settings منتخب کریں، پھر Timezone کی value تبدیل کریں۔ یہ صرف اسی workflow کے لیے GENERIC_TIMEZONE کو override کرتا ہے۔

Schedule Trigger کے لیے ترجیح کی ترتیب مقرر ہے۔ اگر workflow میں timezone مقرر ہو تو n8n workflow timezone استعمال کرتا ہے۔ ورنہ GENERIC_TIMEZONE سے instance timezone استعمال ہوتا ہے۔ اگر یہ بھی موجود نہ ہو تو n8n اپنا built-in default America/New_York استعمال کرتا ہے۔ اس فیصلے کے کسی مرحلے پر TZ کو نہیں دیکھا جاتا۔

آپ کے nodes کے اندر dates کے لیے جواب اس بات پر منحصر ہے کہ code کس clock سے وقت لیتا ہے۔ n8n expressions کے پیچھے استعمال ہونے والی date library Luxon، n8n timezone استعمال کرتی ہے، اس لیے $now اور $today بھی trigger کی طرح workflow-then-instance ترتیب کی پیروی کرتے ہیں۔ Code node میں plain JavaScript new Date() operating system سے وقت لیتا ہے، اس لیے یہ TZ کی پیروی کرتا ہے۔ زیادہ تر الجھن اسی فرق سے پیدا ہوتی ہے: trigger درست وقت پر چل سکتا ہے، جبکہ workflow کے لکھے ہوئے تمام timestamps میں کئی گھنٹوں کا فرق ہو سکتا ہے۔

Compose فائل میں تینوں کو مقرر کریں

فائل میں TZ اور GENERIC_TIMEZONE کو ایک دوسرے کے ساتھ رکھیں، تاکہ کوئی ایک کو مقرر کرکے دوسرے کو بھول نہ جائے۔ ذیل کا حصہ کام کرنے والی service کا 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 کے ساتھ چلاتا ہے جس کے ساتھ وہ بنایا گیا تھا۔ اس لیے فائل تبدیل ہو جاتی ہے، لیکن چلنے والا process تبدیل نہیں ہوتا۔ up -d تبدیل شدہ environment کو دیکھتا ہے اور container کو دوبارہ بناتا ہے۔ اگر آپ یہ values inline رکھنے کے بجائے env file میں رکھتے ہیں، تو یہی recreate rule لاگو ہوتا ہے، اور Compose env file اور secrets handling گائیڈ بتاتی ہے کہ وہ فائل کہاں سے پڑھی جاتی ہے۔

Region/City میں IANA (Internet Assigned Numbers Authority) کا zone name استعمال کریں، مثلاً Europe/Berlin یا America/Sao_Paulo۔ ان names میں اس مقام کے daylight saving rules شامل ہوتے ہیں، اس لیے مقامی گھڑیوں کے مطابق offset تبدیل ہوتا ہے۔ Etc/GMT+5 جیسا fixed-offset name موسم کے ساتھ کبھی تبدیل نہیں ہوتا، اور اس کا sign آپ کے اندازے کے برعکس ہوتا ہے۔ LC_ALL=C TZ=Etc/GMT+5 date +%z چلائیں؛ یہ -0500 دکھاتا ہے۔ ان names سے گریز کریں۔

صرف ایک کو ترتیب دینے سے مسئلہ آدھا ہی حل ہوتا ہے

صرف GENERIC_TIMEZONE ترتیب دینے سے Schedule Trigger مطلوبہ وقت پر فعال ہو جاتا ہے، جبکہ آپریٹنگ سسٹم سے وقت پڑھنے والی ہر چیز UTC پر رہتی ہے۔ new Date().toString() کو کال کرنے والا Code node UTC string واپس کرتا ہے، container کے log lines پر UTC کا وقت درج ہوتا ہے، اور system clock سے بنایا گیا ہر file name غلط نصف شب پر اگلے دن میں منتقل ہو جاتا ہے۔

صرف TZ ترتیب دینے سے اس کے برعکس صورت حال پیدا ہوتی ہے۔ docker compose exec n8n date آپ کا مقامی وقت دکھاتا ہے، جس سے کامیابی کا تاثر ملتا ہے، جبکہ Schedule Trigger اب بھی America/New_York پر ہے اور آپ کے مطلوبہ وقت سے چھ گھنٹے پہلے یا بعد فعال ہوتا ہے۔ اس صورت میں سب سے زیادہ وقت ضائع ہوتا ہے، کیونکہ زیادہ تر لوگ جو ابتدائی جانچ کرتے ہیں، وہی اب کامیاب دکھائی دیتی ہے۔

پہلے workflow timezone ترتیب دیں، پھر بعد میں GENERIC_TIMEZONE تبدیل کریں، تو وہ workflow اس تبدیلی کو نظرانداز کرتا ہے۔ workflow کی اپنی قدر ترجیح رکھتی ہے، اور یہ ترجیح اس وقت تک برقرار رہتی ہے جب تک کوئی اس workflow کی settings نہیں کھولتا۔ اگر ایک workflow عجیب وقت پر چل رہا ہو جبکہ اس کے ساتھ والے workflows درست ہوں، تو تقریباً ہمیشہ یہی وجہ ہوتی ہے۔

اندازہ لگانے کے بجائے گھڑیوں کی جانچ کریں

Host اور container کے وقت کا براہِ راست موازنہ کریں۔

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

پہلے دو commands کو TZ set ہونے کے بعد ایک ہی wall-clock time دکھانا چاہیے۔ printenv موجود ہر variable کے لیے ایک سطر دکھاتا ہے، اس لیے output میں دو سطروں کا مطلب ہے کہ دونوں set ہیں، جبکہ ایک سطر کا مطلب ہے کہ آپ ابھی half-fixed حالت دیکھ رہے ہیں۔

اب workflow کے اندر سے خود n8n سے پوچھیں، کیونکہ 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 ترتیب کے ذریعے پہلے ہی resolve ہو چکا ہے، اس لیے یہ سوال کا براہِ راست جواب دیتا ہے۔ system_time، TZ سے container کا اپنا zone حاصل کرتا ہے۔ اسے کسی نئے workflow کے بجائے اسی غلط رویہ دکھانے والے workflow میں چلائیں، کیونکہ workflow-level setting workflow کے ساتھ منتقل ہوتی ہے۔ اگر یہ دونوں values مختلف ہوں تو کسی ایک config file کو کھولے بغیر مسئلہ معلوم ہو گیا ہے۔

Schedule Trigger node میں Cron expressions

Schedule Trigger، seconds سے months تک مقررہ intervals فراہم کرتا ہے۔ ان intervals میں شامل نہ ہونے والے معاملات کے لیے Custom (Cron) استعمال کریں۔ Cron expression workflow کے resolved timezone کے مطابق پڑھی جاتی ہے۔ اس لیے 0 6 * * * کا مطلب اس zone میں 06:00 ہے، نہ کہ 06:00 UTC۔ crontab guru کی five-field expression جوں کی توں paste کی جا سکتی ہے۔ n8n ایک optional seconds field بھی قبول کرتا ہے۔ documentation کی field table میں یہ field سب سے پہلے آتی ہے: second، minute، hour، day of month، month، day of week۔

Offset خود درج نہ کریں۔ UTC instance پر Berlin میں 06:00 کے لیے 0 4 * * * لکھنا سردیوں میں درست ہوگا، لیکن پوری گرمیوں میں ایک گھنٹہ غلط ہوگا، کیونکہ Berlin سردیوں میں UTC+1 اور گرمیوں میں UTC+2 استعمال کرتا ہے۔ Zone مقرر کریں اور وہ local hour لکھیں جو آپ واقعی چاہتے ہیں۔

02:30 کے لیے مقرر کردہ job پر daylight saving کا اثر

مقامی wall-clock وقت کسی یقینی instant کی ضمانت نہیں دیتا۔ سال میں دو بار ایک گھنٹہ غائب ہو جاتا ہے اور ایک گھنٹہ دوبارہ آتا ہے، اس لیے ان اوقات کے دوران مقرر کردہ ہر job متاثر ہوتی ہے۔ آپ کسی بھی Linux box پر date کے ذریعے، n8n کے بغیر، یہ صورتِ حال دیکھ سکتے ہیں۔

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

یہ command میں typo نہیں ہے۔ 2027-03-28 کو Berlin کی گھڑی براہِ راست 02:00 سے 03:00 ہو جاتی ہے، اس لیے اس دن مقامی 02:30 موجود ہی نہیں ہوتا، اور date اسے کسی instant میں تبدیل کرنے سے انکار کرتا ہے۔ مقامی 02:30 سے وابستہ job کے چلنے کے لیے کوئی وقت موجود نہیں ہوتا۔ اس کے آس پاس کے اوقات درست ہیں: date -d '2027-03-28 01:30' کو CET کے طور پر اور date -d '2027-03-28 03:30' کو CEST کے طور پر resolve کیا جاتا ہے۔

خزاں میں ہونے والی تبدیلی اس کے برعکس ہوتی ہے۔ 2027-10-31 کو Berlin کی گھڑی 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

دو مختلف instants، دونوں مقامی 02:30 کہلاتے ہیں، اور ان کے درمیان 3600 seconds کا فرق ہوتا ہے۔ وہاں مقرر کردہ job یا تو دو بار چلتی ہے یا ایسے گھنٹے میں ایک بار چلتی ہے جسے کسی نے منتخب نہیں کیا تھا۔ billing run یا backup rotation کے لیے دونوں نتائج نامناسب ہیں۔ schedule کو اس window سے باہر منتقل کریں۔ بیشتر European اور North American zones میں خطرناک band مقامی 00:00 سے 03:00 تک ہوتا ہے۔

انفراسٹرکچر کا شیڈول UTC میں بنائیں اور لوگوں کو مقامی وقت دکھائیں

معیاری طریقہ یہ ہے کہ timezone کے دو کام الگ رکھے جائیں۔ مشینوں کو ایک مستقل وقفہ درکار ہوتا ہے۔ لوگوں کو پڑھنے کے قابل وقت درکار ہوتا ہے۔

  • ایسے کام جنہیں کوئی شخص نہیں دیکھتا، ان کے workflow timezone کو UTC پر مقرر کریں۔ Backups، cache warming، log shipping اور report generation اسی زمرے میں آتے ہیں۔ UTC میں سال کے ہر دن دو runs کے درمیان وقفہ بالکل وہی رہتا ہے جو آپ نے مقرر کیا ہے، کیونکہ UTC میں daylight saving نہیں ہوتا۔
  • ایسے کام جنہیں کوئی شخص پڑھتا ہے، ان کا schedule UTC میں رکھیں اور display کے وقت اسے تبدیل کریں۔ ایک expression کافی ہے: {{ $now.setZone('Europe/Berlin').toFormat('yyyy-MM-dd HH:mm') }} message body میں مقامی وقت شامل کرتا ہے، جبکہ trigger مستقل رہتا ہے۔

یہی تقسیم n8n سے باہر بھی لاگو ہوتی ہے۔ جب automation کا کوئی حصہ VPS پر systemd service اور timer کے طور پر چلتا ہے، تو اس کی OnCalendar لائن system timezone کے مطابق پڑھی جاتی ہے، جو اپنی الگ setting والی چوتھی گھڑی ہے۔ ہر scheduler کو UTC پر رکھنے سے آپ کو چار کے بجائے صرف ایک rule یاد رکھنا پڑتا ہے۔ یہ ان کاموں کے لیے بھی اہم ہے جو کسی مدت کا خلاصہ تیار کرتے ہیں، کیونکہ yesterday's numbers کے لیے n8n AI agent workflow سے پوچھنے پر استعمال ہونے والے 24 گھنٹے اس zone کے مطابق خاموشی سے بدل جائیں گے جس میں وقت resolve ہوا ہو۔

ناکامی کی صورتیں اور نظر آنے والا output

ہر چیز تقریباً چھ گھنٹے کے فرق سے چل رہی ہے۔ GENERIC_TIMEZONE مقرر نہیں کیا گیا تھا، اس لیے built-in default America/New_York لاگو ہو رہا ہے۔ docker compose exec n8n printenv GENERIC_TIMEZONE بالکل کچھ بھی print نہیں کرتا۔ اسے set کریں، پھر container دوبارہ بنائیں۔

آپ نے Compose file میں ترمیم کی، لیکن کچھ تبدیل نہیں ہوا۔ آپ نے docker compose restart چلایا، اس لیے container نے اپنا اصل environment برقرار رکھا۔ docker compose up -d چلائیں، پھر docker compose exec n8n printenv TZ سے تصدیق کریں۔

trigger درست ہے، لیکن timestamps غلط ہیں۔ صرف GENERIC_TIMEZONE set ہے۔ Code node میں موجود new Date() اب بھی operating system سے UTC پڑھتا ہے۔ TZ کو اسی value پر set کریں اور container دوبارہ بنائیں۔

ایک workflow instance کی setting نظرانداز کر رہا ہے۔ اس workflow کی settings میں اپنا timezone موجود ہے، جو GENERIC_TIMEZONE پر ترجیح رکھتا ہے۔ canvas کھولیں، تین dots منتخب کریں، پھر Settings اور Timezone کھولیں۔

ایک daily job اس سال ایک بار دو مرتبہ چلا، یا ایک دن skip کر گیا۔ اس کا scheduled hour daylight saving transition کے دوران آتا ہے۔ hour تبدیل کریں، یا اس workflow کو UTC پر منتقل کریں۔

FAQ

میرے n8n schedule trigger کے چلنے کا وقت غلط کیوں ہوتا ہے؟

Workflow آپ کے فرض کردہ timezone کے بجائے کوئی دوسرا timezone استعمال کر رہا ہے۔ n8n پہلے workflow timezone استعمال کرتا ہے، اگر workflow میں یہ مقرر کیا گیا ہو۔ بصورت دیگر یہ GENERIC_TIMEZONE میں موجود instance timezone استعمال کرتا ہے، اور اگر وہ بھی مقرر نہ ہو تو America/New_York کا built-in default استعمال کرتا ہے۔ اگر self-hosted instance میں کسی نے GENERIC_TIMEZONE مقرر نہ کیا ہو تو schedules New York time کے مطابق چلتے ہیں، UTC کے مطابق نہیں۔ اسی لیے offset عموماً UTC سے آپ کے اپنے فرق سے میل نہیں کھاتا۔ docker compose exec n8n printenv GENERIC_TIMEZONE چلائیں۔ اگر کوئی output نہ آئے تو یہ کبھی مقرر نہیں کیا گیا۔

n8n میں TZ اور GENERIC_TIMEZONE میں کیا فرق ہے؟

TZ container کے اندر operating system timezone ہے۔ یہ طے کرتا ہے کہ container کے اندر date کیا output دے گا، container log lines میں کون سے timestamps ظاہر ہوں گے، Code node میں new Date() کیا output دے گا، اور وہاں چلنے والی کوئی بھی script کیا دیکھے گی۔ GENERIC_TIMEZONE n8n instance timezone ہے، جسے schedule nodes اور $now جیسی Luxon expressions استعمال کرتی ہیں۔ ایک کو دوسرے کے بغیر مقرر کرنے سے یا تو trigger درست وقت پر چلتا ہے مگر timestamps غلط ہوتے ہیں، یا timestamps درست ہوتے ہیں مگر trigger کئی گھنٹے کے فرق سے چلتا ہے۔ دونوں کو ایک ہی value پر مقرر کریں۔

کیا مجھے workflow timezone مقرر کرنا چاہیے یا GENERIC_TIMEZONE؟

پورے instance کے default کے طور پر GENERIC_TIMEZONE مقرر کریں، اور per-workflow setting صرف اس وقت استعمال کریں جب کوئی workflow واقعی کسی دوسرے zone سے متعلق ہو۔ Workflow value، instance value پر فوقیت رکھتی ہے، اور GENERIC_TIMEZONE میں بعد کی تبدیلیوں کے ساتھ خود تبدیل نہیں ہوتی۔ اس لیے کئی ماہ بعد بھولا ہوا per-workflow override تلاش کرنا مشکل ہو سکتا ہے۔

جب گھڑیاں تبدیل ہوتی ہیں تو 02:30 پر scheduled job کے ساتھ کیا ہوتا ہے؟

یہ local time یا تو موجود ہی نہیں رہتا یا دو مرتبہ آتا ہے۔ LC_ALL=C TZ=Europe/Berlin date -d '2027-03-28 02:30'، date: invalid date '2027-03-28 02:30' واپس کرتا ہے، کیونکہ اس دن Berlin clock، 02:00 سے 03:00 تک آگے بڑھ جاتی ہے۔ 2027-10-31 کو یہی wall-clock reading ایک گھنٹے کے فرق سے دو مختلف instants سے مطابقت رکھتی ہے۔ Scheduled work کو 00:00 سے 03:00 کے local band سے باہر رکھیں، یا workflow کو UTC پر مقرر کریں اور صرف اس جگہ local time میں تبدیل کریں جہاں اسے کوئی شخص پڑھتا ہو۔