WP-Cron není plánovač. Je to kontrola, která běží při načítání stránek: pokaždé, když někdo požádá o stránku, WordPress se podívá do svého seznamu úloh, a pokud je některá po termínu, pošle na pozadí požadavek na wp-cron.php, aby ji spustil. Žádní návštěvníci znamenají žádné úlohy a hodně návštěvníků znamená spoustu kontrol. Oprava, kterou chce většina webů, má tři kroky: přidej define( 'DISABLE_WP_CRON', true ); do wp-config.php, volej wp-cron.php (nebo wp cron event run --due-now) ze skutečného cronu každých pět minut a přes wp cron event list ověř, že se fronta vyprazdňuje. Zbytek článku vysvětluje, proč to funguje, kdy to nemá smysl dělat a jak zjistit, proč plánovaný příspěvek zůstal viset s nápisem „Missed schedule“.
Jak WP-Cron doopravdy funguje#
WordPress drží všechny naplánované úlohy v jednom řádku databáze: v možnosti cron v tabulce wp_options, což je serializované pole s klíči v podobě unixového času. Každá položka uvádí hook (název akce, například wp_version_check nebo publish_future_post), jeho argumenty a u opakovaných úloh interval jako hourly nebo daily. Pluginy přidávají vlastní položky přes wp_schedule_event() nebo wp_schedule_single_event().
Při každém požadavku, hned na začátku načítání, WordPress zavolá wp_cron(). Ta přečte možnost cron a položí si jedinou otázku: je nejstarší časová značka v minulosti? Pokud ne, nic se nestane a náklady jsou zanedbatelné. Pokud je něco na řadě, zavolá spawn_cron(), který udělá následující:
- Zkontroluje zámek, transient
doing_cron. Pokud jiné spuštění začalo před méně nežWP_CRON_LOCK_TIMEOUTsekundami (výchozí hodnota je 60), vzdá to. - Nastaví zámek na aktuální čas.
- Pošle HTTP POST ze serveru sám sobě - takzvaný loopback požadavek - na
https://your-site/wp-cron.php?doing_wp_cron=<timestamp>s časovým limitem 0,01 sekundy a sblockingnastaveným na false, aby na něj stránka návštěvníka nečekala. - Nový požadavek na
wp-cron.phpnačte WordPress, projde úlohy po termínu v pořadí, spustí každý hook, opakované úlohy přeplánuje a jednorázové odstraní.
Na to, k čemu vznikl, je to chytrý návrh: sdílený hosting z let 2000, kde většina uživatelů vůbec nemohla upravovat crontab. Nepotřebuje žádnou konfiguraci a funguje na každém hostingu, kde PHP smí poslat HTTP požadavek na vlastní doménu. Všechny jeho slabiny plynou z toho, že spouštěčem je návštěvník.
- Čas je jen přibližný. Úloha „naplánovaná na 03:00“ poběží při prvním zobrazení stránky po 03:00. Na tichém webu to může být v 07:40.
- Tiché weby se zastaví. Prezentační web s deseti návštěvami denně spustí své hodinové úlohy desetkrát za den, ne čtyřiadvacetkrát.
- Vytížené weby kontrolují pořád. Samotná kontrola je levná, ale každý spuštěný loopback znamená celé načtení WordPressu a dlouhé úlohy soupeří se skutečnými návštěvníky o PHP workery.
- Stránky z cache se nepočítají. Návštěva obsloužená z full-page cache se k PHP vůbec nedostane, takže WP-Cron nespustí. Čím lepší cache, tím méně často cron běží.
- Loopback může tiše selhat. Když server nedosáhne na vlastní veřejnou adresu, na stránce se žádná chyba neobjeví - úlohy prostě nikdy neproběhnou.
Vestavěné intervaly a co na nich běží#
Jádro registruje čtyři intervaly: hourly, twicedaily, daily a weekly. Pluginy přidávají další přes filtr cron_schedules, a proto v seznamu vytíženého webu uvidíš názvy jako every_minute nebo five_minutes. Čerstvá instalace naplánuje hrstku úloh jádra:
| Hook | Interval | Co dělá |
|---|---|---|
wp_version_check | twicedaily | Kontroluje nové vydání WordPressu |
wp_update_plugins | twicedaily | Kontroluje aktualizace pluginů |
wp_update_themes | twicedaily | Kontroluje aktualizace šablon |
wp_scheduled_delete | daily | Po 30 dnech vysype koš |
delete_expired_transients | daily | Maže prošlé transienty |
wp_privacy_delete_old_export_files | hourly | Odstraňuje staré exporty osobních údajů |
wp_site_health_scheduled_check | weekly | Spouští testy Site Health |
Přesné názvy i jejich počet se mezi verzemi WordPressu mění, takže tabulku ber jako typickou, ne jako úplnou, a svůj seznam si ověř přes wp cron event list. Přes cron běží i automatické aktualizace na pozadí a také plánované příspěvky: když naplánuješ příspěvek, WordPress přidá jednorázovou událost publish_future_post na čas příspěvku s jeho ID jako argumentem.
Pak přicházejí pluginy. Zálohovací pluginy plánují svá spuštění, SEO pluginy přestavují sitemapy, bezpečnostní pluginy spouštějí skeny a WooCommerce přináší Action Scheduler, vlastní frontu, která WP-Cron používá jako jeden ze spouštěčů a v e-shopu může nést tisíce čekajících akcí. Na webu s třiceti pluginy je běžné najít šedesát a více událostí, někdy i pár pozůstatků po pluginech, které někdo smazal, aniž by po sobě uklidily.
Registrace vlastní úlohy vypadá takto. Kontrola wp_next_scheduled() je důležitá - bez ní by každé načtení stránky přidalo další kopii události.
<?phpadd_action( 'mysite_nightly_cleanup', 'mysite_do_cleanup' );function mysite_do_cleanup() { // Delete drafts older than 90 days, prune a log table, and so on.}if ( ! wp_next_scheduled( 'mysite_nightly_cleanup' ) ) { wp_schedule_event( strtotime( 'tomorrow 03:15' ), 'daily', 'mysite_nightly_cleanup' );}WP-Cron ukládá časy jako časové značky v UTC. Čas plánovaného příspěvku v editoru se zobrazuje v časovém pásmu webu z Settings, General a WordPress mezi nimi převádí sám, takže na časovém pásmu serveru nezáleží - na serverových hodinách, které jdou prostě špatně, ale ano.
DISABLE_WP_CRON: vypnutí spouštěče při načtení stránky#
Tahle konstanta má úzký a často špatně chápaný účinek. Zabrání wp_cron(), aby se spouštěl při načítání stránek. Nevypíná plánované úlohy, nic neodstraňuje z možnosti cron a wp-cron.php dál spustí všechny úlohy po termínu, když o něj někdo požádá. Odstraňuješ spouštěč, ne plánovač, a proto je konstanta jen polovina změny - druhou polovinou je dát WordPressu nový spouštěč.
define( 'DISABLE_WP_CRON', true );/* That's all, stop editing! Happy publishing. */Dej ji nad řádek „stop editing“. Cokoli umístěného až po načtení wp-settings.php nemá žádný účinek, a to je nejčastější důvod, proč lidé hlásí, že konstanta „nefunguje“.
Kdy WP-Cron nechat být
Ne každý web to potřebuje. Malý blog s rovnoměrnou návštěvností, bez full-page cache před PHP a bez úloh citlivých na čas běží na výchozím nastavení v pořádku a systémový cron je jen další věc, která se rozbije při stěhování k jinému hostingu. Změna má smysl, když platí něco z tohoto:
- Plánované příspěvky nebo e-maily musí odejít včas, ne „někdy potom“.
- Návštěvnost je nízká nebo nepravidelná, takže úlohy běží o hodiny později.
- Většinu požadavků obsluhuje full-page cache nebo CDN, takže PHP návštěvníka vidí jen zřídka.
- Web je vytížený a chceš práci cronu dostat mimo cestu požadavku a z dosahu skutečných návštěvníků.
- Je nainstalovaný WooCommerce, členský plugin nebo cokoli postaveného na Action Scheduleru - jejich fronty při spouštění z načtení stránek rychle zaostávají.
Náhrada skutečným cronem#
Skutečný spouštěč je cokoli, co běží podle hodin a umí buď poslat HTTP požadavek na wp-cron.php, nebo spustit PHP v adresáři WordPressu. Pětipolová syntaxe cronu je všude stejná; pokud */5 * * * * potřebuješ rozluštit, článek výrazy cronu vysvětlené ji rozebírá pole po poli.
Možnost 1: volat wp-cron.php přes HTTP
Funguje to odkudkoli - ze stejného serveru, z jiného serveru, z malého VDS, který už provozuješ, nebo z hostované cron služby - protože jde o obyčejný webový požadavek. Je to jediná možnost, když ti hosting nedává shell.
*/5 * * * * curl -fsS -o /dev/null --max-time 120 "https://example.com/wp-cron.php?doing_wp_cron"Nebo přes wget, který mají některé minimální systémy místo něj:
*/5 * * * * wget -q -O /dev/null --timeout=120 "https://example.com/wp-cron.php?doing_wp_cron"Na --max-time záleží. Bez něj může zaseknutý požadavek zůstat otevřený neomezeně dlouho, zatímco cron o pět minut později spustí další. Úlohy stále běží uvnitř běžného webového požadavku, takže je omezují časové limity webového serveru i samotného PHP - zálohovací plugin, který potřebuje deset minut, může utnout max_execution_time nebo timeout proxy. Který limit je který, rozebírá článek nastavení PHP ini, na kterých záleží.
Možnost 2: spouštět přes WP-CLI
Pokud máš shell na stroji, kde WordPress běží, je WP-CLI lepší spouštěč. Běží pod PHP z příkazové řádky, které obvykle nemá limit doby běhu, nic neprochází webovým serverem a není tu žádný loopback, který by mohl selhat.
*/5 * * * * cd /var/www/example.com && /usr/local/bin/wp cron event run --due-now --quietSpouštěj ho pod stejným uživatelem, kterému patří soubory WordPressu, ne pod rootem. WP-CLI odmítá běžet jako root bez --allow-root z dobrého důvodu: soubory, které úloha vytvoří (cache, nahrané soubory, archivy záloh), by patřily rootovi a webový server by je už nemohl měnit. Pokud může jeden běh trvat déle než interval, obal příkaz do flock -n /tmp/wp-cron-example.lock, aby druhá kopie nestartovala přes první.
Přímé volání php wp-cron.php z adresáře WordPressu také funguje a WP-CLI nepotřebuje, jenže WP-CLI ti dává mnohem lepší nástroje, jak zjistit, co se stalo.
Jak často ho spouštět
| Web | Interval | Proč |
|---|---|---|
| Blog nebo prezentační web | */15 * * * * | Nic nespěchá; příspěvky nanejvýš o 15 minut později |
| Blog s plánovanými příspěvky nebo newslettery | */5 * * * * | Obvyklé výchozí nastavení |
| WooCommerce nebo členství | * * * * * | Fronty Action Scheduleru a opakované platby |
| Síť Multisite | */5 * * * * pro každý web | Každý web má vlastní volbu cron |
Spouštění každou minutu je levné, když nic nečeká - požadavek zkontroluje časovou značku a skončí. Náklady se objeví jen tehdy, když se nahromadí hodně práce, a to ji stejně chceš mít hotovou co nejdřív. U Multisite pamatuj, že každý web má vlastní frontu: projdi ve smyčce wp site list --field=url a pro každý spusť wp cron event run --due-now --url=<site>, nebo volej wp-cron.php každého webu.
WP-CLI: prohlížení a spouštění fronty#
WP-CLI je nejrychlejší způsob, jak odpovědět na otázku „funguje cron?“. První příkaz ukáže všechno, co čeká:
$ wp cron event list --fields=hook,next_run_relative,recurrence+------------------------------------+------------------------+---------------+| hook | next_run_relative | recurrence |+------------------------------------+------------------------+---------------+| publish_future_post | 3 hours 20 minutes ago | Non-repeating || wp_privacy_delete_old_export_files | 2 hours 1 minute ago | 1 hour || wp_version_check | 5 hours 12 minutes | 12 hours || wp_scheduled_delete | 17 hours 4 minutes | 1 day |+------------------------------------+------------------------+---------------+Cokoli s „ago“ je po termínu. Jedna dvě události zpožděné zhruba o minutu jsou normální; celý sloupec událostí, které jsou hodiny v minulosti, znamená, že cron vůbec nikdo nespouští. Užitečné příkazy:
| Příkaz | Co dělá |
|---|---|
wp cron event list | Všechny naplánované události a jejich příští spuštění |
wp cron event run --due-now | Spustí všechny události, jejichž čas už nastal |
wp cron event run <hook> | Spustí jeden hook hned, bez ohledu na plán |
wp cron event schedule <hook> now hourly | Přidá událost |
wp cron event delete <hook> | Odstraní naplánované události hooku |
wp cron schedule list | Vypíše dostupné intervaly |
wp cron test | Ověří, že WP-Cron dokáže spustit loopback |
Spuštění jediného hooku přes wp cron event run <hook> je nejlepší způsob, jak ladit úlohu pluginu: chyby a varování uvidíš přímo v terminálu, místo aby se ztratily v požadavku na pozadí, který nikdo nesleduje. Přidej --debug a uvidíš vlastní výpis WP-CLI o tom, co se načetlo.
wp cron test kontroluje cestu přes načítání stránek - pošle stejný loopback, jaký by poslal spawn_cron(), a zároveň ti řekne, jestli je nastavené DISABLE_WP_CRON. Se zapnutou konstantou je varování očekávané; tehdy záleží na tom, jestli seznam vyprazdňuje tvůj systémový cron.
Pokud shell nemáš, plugin WP Crontrol ukáže stejný seznam přímo v administraci, umožní událost okamžitě spustit a označí události, za jejichž hookem už není žádný kód. Vyplatí se ho nainstalovat kvůli diagnostice a pak zase odebrat.
Zmeškané plánované příspěvky#
„Missed schedule“ v seznamu příspěvků znamená, že událost publish_future_post pro daný příspěvek byla na řadě a neproběhla. WordPress tenhle štítek ukáže, jakmile plánovaný čas uplyne a příspěvek je stále ve stavu future. Téměř vždy jde o jednu z těchto příčin:
- Žádný spouštěč. Mezi plánovaným časem a teď nikdo nepřišel, všechno šlo z cache, nebo je nastavené
DISABLE_WP_CRONbez náhrady. Událost je pořád ve frontě; příští běh cronu příspěvek zveřejní. - Loopback selhává. Server nedosáhne na vlastní doménu. Časté příčiny: DNS webu míří na CDN nebo proxy, na které server zevnitř nedosáhne; hairpin NAT, který zahazuje spojení serveru na jeho vlastní veřejnou adresu; HTTP basic auth na testovacím webu; bezpečnostní plugin nebo firewall, který blokuje požadavky na
wp-cron.php; certifikát podepsaný sám sebou na lokální kopii. - Úloha spadla. Dřívější úloha ve stejném běhu narazila na fatální chybu nebo jí došla paměť a zbytek fronty už neproběhl. Jediný rozbitý hook pluginu dokáže zdržet všechno za sebou.
- Událost zmizela. Příspěvek je naplánovaný, ale
wp cron event listpro něj žádnépublish_future_postneukazuje. To je vzácnější - lidé obvykle najdou souběh, kdy dva požadavky zapisují možnostcronsoučasně, nebo perzistentní objektovou cache, která vrací zastaralou kopii možností.
U prvních tří případů oprava spouštěče opraví i příspěvek: spusť wp cron event run --due-now a příspěvek se zveřejní. U čtvrtého příspěvek otevři a zveřejni ručně, nebo nastav nový čas a naplánuj ho znovu, čímž vznikne čerstvá událost. Existují pluginy, které „zveřejňují zmeškané plánované příspěvky“, a jediné, co dělají, je, že při načtení stránek hledají příspěvky po termínu a zveřejňují je. Je to obejití problému se spouštěčem, ne jeho řešení, a se skutečným cronem je zbytečné.
ALTERNATE_WP_CRON a další obezličky#
define( 'ALTERNATE_WP_CRON', true );ALTERNATE_WP_CRON existuje pro servery, kde loopback fungovat nemůže a skutečný cron přidat nejde. Místo toho, aby WordPress volal sám sebe, přesměruje prohlížeč návštěvníka na stejnou URL s připojeným ?doing_wp_cron= a úlohy po termínu spustí v tomto požadavku po odeslání stránky. Úlohy se tak opravdu spouštějí, ale za cenu: viditelný query string v adresním řádku, přesměrování navíc u toho zobrazení stránky, které ho zrovna vyvolá, varianta URL, která se může dostat do sdílených odkazů nebo do cache, a práce cronu je pořád svázaná s návštěvností. Ber to jako dočasné řešení. Pokud můžeš odkudkoli naplánovat HTTP požadavek na wp-cron.php, udělej to a tuhle konstantu nech vypnutou.
Vyplatí se znát ještě dvě související konstanty. WP_CRON_LOCK_TIMEOUT nastavuje okno zámku v sekundách; zvyšovat ho většině webů nic užitečného nepřinese, ale někdo ho snižuje, když nechává cron při načtení stránek zapnutý a úlohy musí startovat častěji. DISABLE_WP_CRON a ALTERNATE_WP_CRON by neměly být nastavené současně - když je zapnutá první, druhá nedostane šanci zasáhnout.
wp-cron.php, cache a zabezpečení#
I s nastaveným DISABLE_WP_CRON odpovídá wp-cron.php každému, kdo o něj požádá, a spustí všechno, co je na řadě. Obvykle je to neškodné - když nic nečeká, požadavek rychle skončí - ale útočník nebo rozbitý bot, který ho volá ve smyčce, nutí PHP načítat WordPress při každém požadavku. Článek zabezpečení WordPressu ho řadí vedle xmlrpc.php mezi koncové body, které se vyplatí omezit. Pokud tvůj cron běží na stejném stroji přes WP-CLI, nemusí na wp-cron.php přes HTTP přistupovat vůbec nikdo a můžeš ho na webovém serveru zakázat:
location = /wp-cron.php { allow 127.0.0.1; deny all;}Pokud ho přes HTTP volá externí stroj, povol místo 127.0.0.1 jeho adresu, nebo tuto location rate-limituj místo úplného blokování. Neblokuj ji dřív, než náhradní spouštěč funguje, jinak jsi zpátky u zmeškaných plánů.
Jakmile cron běží podle hodin, cache hraje ve tvůj prospěch. Full-page cache před WordPressem, popsaná v článku rychlost a cache ve WordPressu, znamená, že k PHP dorazí méně požadavků, což u cronu z načítání stránek znamenalo méně příležitostí spustit úlohy. Se skutečným spouštěčem si přestanou překážet: cache obsluhuje návštěvníky a cron frontu. Vyjmi wp-cron.php ze všech pravidel cache - většina nastavení to dělá sama, protože požadavek nese query string, ale pravidlo CDN „cachuj všechno“ ho může spolknout.
Důležitá je i paměť. Požadavky cronu běží pod WP_MAX_MEMORY_LIMIT (výchozí 256M), ne pod nižším limitem frontendu, takže náročná úloha může krátce spotřebovat víc než jakékoli zobrazení stránky. Pokud web padá každou noc zhruba ve stejnou dobu, podívej se, co v tu hodinu spouští cron, dřív než to svedeš na návštěvnost - článek kolik RAM potřebuje WordPress ukazuje, jak to změřit.
Cron WordPressu na RE:NODE#
Řada WordPress ve webhostingu RE:NODE nainstaluje WordPress při prvním spuštění s už napsaným wp-config.php pro vlastní databázi MySQL, takže DISABLE_WP_CRON přidáš do souboru, který hned otevřeš ve vestavěném správci souborů nebo přes SFTP. Ve výchozím stavu se nic nemění: WP-Cron běží při načítání stránek úplně stejně jako všude jinde.
Panel má záložku Schedules, která přijímá standardní výraz cronu a spouští seřazené úlohy s prodlevami mezi nimi - příkaz do konzole, zálohu nebo akci napájení (průvodce Schedules ji prochází krok za krokem). U webu na WordPressu je to přirozené místo pro úlohy kolem WordPressu, ne uvnitř něj: noční záloha v hodinu, kdy nikdo z redaktorů nepracuje, a záloha pár minut před plánovanou hromadnou změnou. Jako obecný způsob, jak zavolat URL, popsaná není, takže pro samotný spouštěč wp-cron.php použij HTTP cron zvenku - jiný server, který provozuješ, nebo libovolnou hostovanou cron službu - s výše uvedeným řádkem curl namířeným na tvou doménu. Web už na vlastní doméně běží přes HTTPS díky proxy slotu tarifu, takže jde o úplně běžný požadavek.
Pro úlohy cronu jsou důležité dvě vlastnosti platformy. CPU je pevně omezené na podíl, který tarif obsahuje, takže náročná úloha na malém tarifu běží pomalu, ale nespadne; a pokud úloha dostane server přes limit paměti, kontejner se zastaví a čistě restartuje, místo aby swapoval, což daný běh cronu ukončí v půlce. Pokud je noční úloha tak velká, že narazí na jedno nebo druhé, rozlož ji v čase nebo přejdi na vyšší tarif - obecný postup popisuje článek úlohy na pozadí na malém serveru.
Kontrolní seznam při řešení potíží#
Události v `wp cron event list` mají zpoždění v hodinách. Cron nic nespouští. Pokud je nastavené DISABLE_WP_CRON, tvůj systémový cron neběží nebo na web nedosáhne - spusť přesně ten řádek curl ručně a podívej se na stavový kód. Pokud nastavené není, web má příliš málo návštěv mimo cache, nebo selhává loopback; wp cron test ti řekne, co z toho.
Řádek curl vrací 403 nebo přihlašovací stránku. Požadavek blokuje bezpečnostní plugin, webový aplikační firewall nebo basic auth. Povol adresu volajícího stroje, nebo přejdi na spouštěč přes WP-CLI na stejném stroji.
Řádek curl vrací 200, ale nic neproběhne. Zkontroluj, že URL je skutečná adresa webu a ne přesměrování na www nebo HTTPS - přidej -L, aby ho curl následoval, nebo raději rovnou použij cílovou URL. U Multisite ověř, že voláš správný web.
Jedna úloha nikdy nedoběhne a všechno za ní se zpožďuje. Spusť ten hook samostatně přes wp cron event run <hook> a přečti si chybu. Fatální chyby v požadavcích na pozadí končí v chybovém logu PHP, ne na obrazovce, takže po dobu hledání zapni WP_DEBUG_LOG a potom ho zase vypni.
Stejná úloha běží dvakrát. Jsou aktivní dva spouštěče - cron z načítání stránek a systémový cron, nebo dva řádky v crontabu po starém nastavení. Nastav DISABLE_WP_CRON a nech přesně jeden plán.
Stovky událostí od pluginu, který jsi smazal. Plugin po sobě nechal své hooky. Odstraň je přes wp cron event delete <hook> nebo pluginem WP Crontrol. Neškodí, ale zaplevelují seznam a ztěžují odhalení skutečných problémů.
FAQ#
Zastaví DISABLE_WP_CRON zveřejňování plánovaných příspěvků?
Jen pokud cron nespouští nic jiného. Konstanta odstraní spouštěč z načítání stránek; plánované události zůstanou ve frontě a proběhnou, jakmile něco zavolá wp-cron.php nebo je spustí WP-CLI. Ve spojení se skutečným cronem vycházejí plánované příspěvky přesněji, ne naopak.
Jak často má skutečný cron volat wp-cron.php?
Většině webů vyhovuje každých pět minut. E-shopům a všemu, co používá Action Scheduler, se daří lépe s každou minutou, a web bez časově citlivé práce si vystačí s patnácti. Běh, kdy nic nečeká, stojí jeden krátký PHP požadavek.
Dá se WP-Cron spouštět bez přístupu k shellu?
Ano. Spouštěč musí jen poslat HTTPS požadavek na tvůj web, takže může běžet kdekoli: v hostované cron službě, na VPS, který už máš, nebo na domácím serveru kamaráda. Použij řádek curl s časovým limitem a namiř ho na cílovou URL webu.
Je bezpečné používat ALTERNATE_WP_CRON?
Funguje a nebezpečné není, ale ukazuje návštěvníkům query string, přidává přesměrování a pořád závisí na návštěvnosti. Používej ho jen tehdy, když loopback selhává a není žádná možnost naplánovat požadavek zvenku.
Proč Site Health hlásí, že se plánovaná událost zpožďuje?
Site Health porovná čas každé události s aktuálním a označí ty, které jsou po termínu. Jedna opožděná událost obvykle znamená pomalý spouštěč; celý seznam znamená, že cron neběží. Ověř to přes wp cron event list a oprav spouštěč, ne varování.
Rozbije stránková cache WP-Cron?
Oslabí ho. Odpovědi z cache se k PHP nedostanou, takže cron nespustí. Na dobře cachovaném webu s cronem z načítání stránek mohou úlohy na necachovaný požadavek čekat dlouho. Přechod na skutečný cron to vyřeší úplně.


