Laravel Scheduler: Tư duy thiết kế, trade-off và best practices cho hệ thống lớn

Nếu bạn đã đi làm vài năm, bạn sẽ thấy “Scheduler” không phải chuyện viết vài dòng dailyAt(). Nó là bài toán reliability + performance + observability. Sai một ly là: trùng charge, spam notify, kẹt DB lúc 9h, hoặc “đêm qua không chạy mà không ai biết”.

Bài này chia sẻ theo góc nhìn hệ thống lớn: ra quyết định kỹ thuật khi số job tăng nhanh, dữ liệu lớn, nhiều worker, CI/CD liên tục, thậm chí realtime.


1. Nguyên tắc số 1: Scheduler phải “nhẹ” — việc nặng đẩy qua queue

Tư duy: Scheduler là “orchestrator”, không phải “executor”.

Scheduler chỉ làm 2 việc:

  • Quyết định “đúng giờ thì trigger cái gì”
  • Dispatch nhanh, ghi dấu vết (batch metadata)

Việc nặng (DB scan, gọi API, gửi notify hàng loạt, reconcile, billing…) → chạy trong queued jobs + nhiều worker.

Trade-off:

  • ✅ Ưu: Scale bằng worker, retry/backoff chuẩn, tách tải khỏi scheduler
  • ⚠️ Nhược: Job có thể chạy trễ → phải thiết kế theo “batch time” (xem phần 4)

Sai lầm thường gặp: Nhét logic nặng vào scheduler (closure/command) rồi “đỡ nghẽn” bằng cách tăng CPU. Đến lúc 100 lịch/ngày thì scheduler thành single-point bottleneck.

Ví dụ:

<?php

// routes/console.php
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schedule;

// ❌ SAI: Logic nặng trực tiếp trong scheduler
Schedule::call(function () {
    DB::table('recent_users')->chunk(100, function ($users) {
        foreach ($users as $user) {
            // Process payment, send email, update DB...
            // Nếu có 1000 users, scheduler sẽ bị block rất lâu
        }
    });
})->dailyAt('09:00');

// ✅ ĐÚNG: Scheduler chỉ dispatch job
Schedule::job(new ProcessRecentUsersJob)
    ->dailyAt('09:00');

Scheduler chỉ trigger đúng giờ, không bao giờ chạy logic business trực tiếp. Worker sẽ xử lý job trong queue.


2. “Đúng một lần” theo nghĩa business > “đúng một lần” theo nghĩa kỹ thuật

Ở hệ thống lớn, “at least once” là mặc định. Scheduler/queue/worker/retry/deploy đều có thể làm job chạy lại.

Best practice: Thiết kế job theo idempotent:

  • Chạy 2 lần vẫn ra kết quả đúng
  • Side-effect (charge/send/update) phải có khóa logic hoặc unique key

Dùng lock ở đúng tầng:

  • Tầng scheduler: Chống chồng / chạy một server (khi HA)
  • Tầng job/business: Lock theo entity/time-window (mới là thứ bảo vệ cuối)

Trade-off:

  • Lock nhiều quá → Giảm throughput, dễ nghẽn nếu lock sai granularity
  • Lock ít quá → Trùng dữ liệu/side-effect

Sai lầm thường gặp: Tin tuyệt đối vào “chống chồng” của scheduler rồi bỏ qua idempotency. Một ngày deploy “đúng lúc”, bạn sẽ hiểu.

Ví dụ:

Job có idempotency key dựa trên entity_id + batch_time. Concept này áp dụng cho mọi job có side-effect quan trọng. Trong scheduler, bạn chỉ dispatch job với metadata:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::job(new ProcessOrdersJob)
    ->dailyAt('09:00');

Job sẽ tự implement idempotency check trong handle() method để đảm bảo không xử lý trùng.


3. Khi nào dùng runInBackground() và khi nào “bắt buộc” dùng queue?

Tôi coi runInBackground() là giải pháp tactical, không phải chiến lược lâu dài.

Dùng runInBackground() khi:

  • Task là command/exec tương đối ngắn
  • Không cần scale theo tải
  • Bạn chỉ cần tránh scheduler bị giữ process quá lâu

Bắt buộc đưa qua queue khi:

  • Task có thể chạy vài chục giây/phút
  • Task có thể “nở” theo dữ liệu (data grows)
  • Task có side-effect quan trọng (payment/notify hàng loạt)
  • Cần retry/backoff, rate-limit, phân ưu tiên

Sai lầm thường gặp: “Task đang lâu → thêm runInBackground()” và coi như xong. Thực tế bạn chỉ chuyển nghẽn từ scheduler sang CPU/DB/connections của cùng máy.

Ví dụ:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// ✅ Dùng runInBackground cho command nhẹ, không cần scale
Schedule::command('cache:clear')
    ->hourly()
    ->runInBackground();

Schedule::command('emails:send')
    ->dailyAt('02:00')
    ->runInBackground();

// ✅ Bắt buộc dùng queue cho job có side-effect quan trọng
Schedule::job(new SendOrderConfirmationJob)
    ->dailyAt('09:00'); // Không có runInBackground, vì đã là queued job

Chỉ có 2 loại command dùng runInBackground():

  1. Maintenance commands (cleanup, cache) — không ảnh hưởng business
  2. Monitoring commands — cần chạy nhanh, không cần retry

Tất cả job business đều qua queue để có retry/backoff/scale.


4. Bài toán lớn nhất của hệ queue: Job chạy trễ → lệch cửa sổ dữ liệu

Đây là điểm phân biệt hệ “chạy được” và hệ “chạy đúng”.

Vấn đề:

  • Scheduler trigger 09:00, worker chạy 09:04
  • Nếu job query theo now() lúc 09:04, bạn vừa:
    • Miss dữ liệu 09:00–09:04 (tùy window)
    • Hoặc duplicate với batch trước

Giải pháp: Scheduler đóng dấu batch time ngay lúc dispatch (tôi hay gọi scheduledAt/batchAt). Job luôn dùng scheduledAt để:

  • Tính window dữ liệu
  • Log/audit theo batch
  • Tạo idempotency key

Trade-off:

  • Tốn thêm metadata, thêm “kỷ luật” trong code
  • Đổi lại: Batch chạy trễ vẫn đúng cửa sổ, dễ đối soát, dễ replay theo batch

Ví dụ — Pattern batch timestamp:

Concept: Scheduler đóng dấu batch time ngay lúc dispatch. Job nhận batch time và dùng để tính time window, không dùng now().

Sử dụng trong Laravel 12:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::job(new ProcessOrdersJob)
    ->dailyAt('09:00');

Job sẽ nhận scheduledAt từ scheduler event và dùng để query đúng time window.

Ví dụ với sub-minute scheduling trong Laravel 12:

Theo Laravel 12.x Sub-Minute Scheduled Tasks:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// Laravel 12 hỗ trợ sub-minute scheduling
Schedule::call(function () {
    // Process tasks every 30 seconds
})->everyThirtySeconds();

Lợi ích:

  • Job chạy trễ 3 phút vẫn query đúng cửa sổ 09:00–09:01
  • Dễ đối soát: “Batch 09:00 đã xử lý bao nhiêu records?”
  • Dễ replay: “Chạy lại batch 09:00” → chỉ cần tạo job với jobCreatedAt = 09:00

5. Tách “workload shape”: Phân queue theo ưu tiên, tránh job “rác” ăn tài nguyên job “sống còn”

Một hệ thống lớn sẽ có job kiểu:

  • Critical: Billing, payment, cancel, inventory, security
  • Default: Vận hành
  • Low: Marketing, remind, digest

Best practice: Tách queue theo priority, scale worker theo queue. Đặt rule: Job low không bao giờ được làm chậm job critical.

Trade-off:

  • Nhiều queue → Config vận hành phức tạp hơn (supervisor/horizon)
  • Nhưng nếu không tách, bạn sẽ gặp kiểu “19h campaign bắn notify” làm nghẽn payment

Lưu ý: Trong scheduler, bạn có thể chỉ định queue khi schedule job:

Theo Laravel 12.x Scheduling Queued Jobs, method job() nhận queue name làm tham số thứ 2:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::job(new SendOrderConfirmationJob, 'critical')
    ->dailyAt('09:00');

Hoặc nếu job class đã có property $queue, scheduler sẽ tự động dùng queue đó.


6. “Thundering herd” lúc tròn giờ: Kẻ thù của DB và API

Hệ thống lớn rất hay bị “dồn lịch” vào 00:00, 09:00, 12:00, 19:00…

Best practice:

  • Stagger: Dàn đều theo phút/giây
  • Nếu bắt buộc tròn giờ: Chia nhỏ thành nhiều job chunk, có rate-limit/backoff
  • Không quét toàn bảng: Dùng cursor/chunk theo index, watermark theo batch

Sai lầm thường gặp: Một job “tổng hợp cuối ngày” chạy 00:00 quét cả bảng 50 triệu dòng. Đêm đó DB chết, sáng không ai biết vì không có alert.

Ví dụ — Stagger pattern trong scheduler:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// Dàn đều theo phút để tránh thundering herd
$times = ['9:03', '10:03', '11:03', '12:03', '13:03', '14:03', '15:03', '16:03', '17:03', '18:03', '19:03', '20:03', '21:03'];

foreach ($times as $time) {
    Schedule::job(new ProcessHourlyTaskJob)
        ->at($time);
}

7. Observability là bắt buộc: “Không ai biết scheduler fail” = thất bại hệ thống

Scheduler fail nguy hiểm vì nó âm thầm.

Best practice:

  • Log theo batch (scheduledAt, job name, duration, result)
  • Có alert khi fail (hook/event/ping tùy hệ)
  • Có “schedule inventory”: Định kỳ audit lịch chạy (ít nhất kiểm lịch sau deploy)

Trade-off:

  • Thêm log/metrics → Tốn công + tốn storage
  • Nhưng thiếu nó thì khi sự cố xảy ra, bạn mất nhiều giờ “đào mộ”

Ví dụ — Scheduler hooks trong Laravel 12:

Theo Laravel 12.x Task Hooks:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')
    ->daily()
    ->before(function () {
        // The task is about to execute...
    })
    ->after(function () {
        // The task has executed...
    })
    ->onSuccess(function () {
        // The task succeeded...
    })
    ->onFailure(function () {
        // The task failed...
    });

Scheduler setup:

# Cron entry
* * * * * cd /path-to-app && php artisan schedule:run >> /dev/null 2>&1

Kiểm tra lịch chạy:

# Laravel 12: Xem tất cả scheduled tasks
php artisan schedule:list

8. CI/CD & Deploy: Đừng để deploy tạo ra double-run / half-run

Ở môi trường deploy liên tục, scheduler/worker cần “graceful”:

Best practice:

  • Tránh chạy song song 2 version job logic cho cùng một batch
  • Worker restart có kiểm soát; job quan trọng có idempotency key để chịu được retry/duplicate
  • Nếu hệ HA nhiều scheduler node: Phải có chiến lược “one server” + shared lock store

Sai lầm thường gặp: Deploy xong “mọi thứ xanh”, nhưng lịch 09:00 bị chạy 2 lần vì 2 scheduler node cùng tick.

Ví dụ — Laravel 12 onOneServer():

Theo Laravel 12.x Running Tasks on One Server:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// Nếu có nhiều scheduler server, dùng onOneServer() để chạy chỉ trên 1 server
Schedule::command('emails:send')
    ->daily()
    ->onOneServer(); // Chỉ chạy trên 1 server, dùng cache để lock

Lưu ý: Job vẫn phải idempotent vì:

  • Retry khi fail
  • Deploy có thể làm job chạy lại
  • Worker restart có thể làm job chạy lại

9. Tổ chức code: Khi Kernel.php “phình to”

Khi số lượng lịch tăng, Kernel.php sẽ rất dài (có thể lên 300+ lines).

Best practice — Laravel 12: Tách helper functions theo domain để dễ maintain:

Theo Laravel 12.x Defining Schedules, bạn có thể định nghĩa trong routes/console.php và tách thành helper functions:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// Tách theo domain để dễ maintain
schedulePaymentTasks();
scheduleNotificationTasks();
scheduleCleanupTasks();

function schedulePaymentTasks(): void
{
    Schedule::command('payments:process')
        ->dailyAt('09:00');

    Schedule::command('payments:retry')
        ->dailyAt('14:00');
}

function scheduleNotificationTasks(): void
{
    Schedule::command('notifications:send')
        ->hourly();

    Schedule::command('notifications:digest')
        ->dailyAt('20:00');
}

function scheduleCleanupTasks(): void
{
    Schedule::command('cache:clear')
        ->hourly()
        ->runInBackground();
}

Hoặc dùng withSchedule trong bootstrap/app.php và tách thành methods:

<?php

// bootstrap/app.php
use Illuminate\Console\Scheduling\Schedule;

->withSchedule(function (Schedule $schedule) {
    schedulePaymentTasks($schedule);
    scheduleNotificationTasks($schedule);
    scheduleCleanupTasks($schedule);
});

function schedulePaymentTasks(Schedule $schedule): void
{
    $schedule->command('payments:process')->dailyAt('09:00');
    $schedule->command('payments:retry')->dailyAt('14:00');
}

Lợi ích:

  • Dễ review: Mỗi function = 1 domain
  • Dễ test: Có thể test từng domain riêng
  • Dễ ownership: Team có thể own từng domain
  • Tránh Kernel.php phình to: Code nằm trong routes/console.php hoặc helper functions

Schedule Groups — Laravel 12:

Theo Laravel 12.x Schedule Groups, bạn có thể nhóm các tasks có cùng cấu hình để tránh lặp lại code:

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// ❌ SAI: Lặp lại cấu hình cho từng task
Schedule::command('emails:send')
    ->daily()
    ->onOneServer()
    ->timezone('America/New_York');

Schedule::command('emails:prune')
    ->daily()
    ->onOneServer()
    ->timezone('America/New_York');

// ✅ ĐÚNG: Dùng Schedule Groups để nhóm tasks có cùng cấu hình
Schedule::daily()
    ->onOneServer()
    ->timezone('America/New_York')
    ->group(function () {
        Schedule::command('emails:send');
        Schedule::command('emails:prune');
    });

Lợi ích của Schedule Groups:

  • Giảm lặp lại code: Không cần lặp lại onOneServer(), timezone(), withoutOverlapping() cho từng task
  • Dễ maintain: Thay đổi cấu hình một lần áp dụng cho cả nhóm
  • Tăng tính nhất quán: Đảm bảo tất cả tasks trong nhóm có cùng cấu hình

10. Timezone handling: Luôn nhất quán

Best practice: Cố định timezone theo business, không dùng server timezone. Nguyên tắc: Tất cả scheduled tasks phải dùng cùng một business timezone để đảm bảo tính nhất quán.

Ví dụ — Laravel 12 timezone:

Theo Laravel 12.x Scheduling Timezones, có 2 cách set timezone:

Cách 1: Set timezone trong config (khuyến nghị):

Khi tất cả tasks dùng cùng business timezone, thêm schedule_timezone vào config/app.php:

<?php

// config/app.php
return [
    'timezone' => 'UTC', // Application timezone

    'schedule_timezone' => 'Asia/Tokyo', // Business timezone cho scheduled tasks
];

Với cấu hình này, tất cả scheduled tasks sẽ tự động dùng timezone Asia/Tokyo trừ khi được ghi đè bởi method timezone() trong từng task cụ thể.

Cách 2: Set timezone cho từng task riêng:

Chỉ định timezone cho task cụ thể bằng method timezone():

<?php

// routes/console.php
use Illuminate\Support\Facades\Schedule;

// Set timezone cho task cụ thể (ghi đè config)
Schedule::command('report:generate')
    ->timezone('America/New_York')
    ->at('2:00');

Lưu ý quan trọng về DST (Daylight Saving Time):

Theo Laravel 12.x Scheduling Timezones, một số timezone sử dụng DST có thể ảnh hưởng đến thời gian thực thi. Khi DST thay đổi, task có thể chạy 2 lần hoặc không chạy. Nên tránh dùng timezone có DST khi có thể.

Nguyên tắc áp dụng:

  • ✅ Nên: Set timezone một lần trong config/app.php với key schedule_timezone nếu tất cả tasks dùng cùng business timezone
  • ⚠️ Tránh: Set timezone cho từng task riêng lẻ → dễ quên, dễ sai, khó maintain
  • ⚠️ Tránh: Dùng timezone có DST → có thể ảnh hưởng đến thời gian thực thi khi DST thay đổi

Kết luận: Framework cho quyết định kỹ thuật

Khi thêm một scheduled task mới, tôi tự hỏi 6 câu:

  1. Task này có side-effect quan trọng không? → Nếu có → Idempotent + audit batch
  2. Dữ liệu tăng thì task tăng theo tuyến nào? → Nếu O(N) theo bảng lớn → Phải có watermark/chunk/index
  3. Chạy trễ có làm sai cửa sổ dữ liệu không? → Nếu có → Cần scheduledAt/batchAt
  4. Có được phép chạy song song không? → Nếu không → Overlap guard + lock theo business key
  5. Nó thuộc priority nào? → Nếu không critical → Đừng để nó chạy chung queue với critical
  6. Fail thì ai biết, trong bao lâu? → Nếu câu trả lời mơ hồ → Bổ sung observability trước

Checklist áp dụng

  •  Scheduler chỉ dispatch queued jobs, không chạy logic nặng
  •  Tất cả job có side-effect đều idempotent
  •  Job dùng batchTime/scheduledAt để tính time window, không dùng now()
  •  Job dùng chunkById hoặc cursor pagination cho data lớn
  •  Job có stagger/rate-limit khi gọi external API
  •  Job log theo batch time để dễ đối soát
  •  Scheduler có helper methods theo domain, không phình to schedule()
  •  Timezone nhất quán: Business timezone, không dùng server timezone
  •  Queue được phân priority (critical/default/low)
  •  Có alert khi scheduler/job fail

Tài liệu tham khảo: Laravel 12.x Task Scheduling

0 Shares:
112 comments
  1. I was very pleased to find this page. I wanted to
    thank you for ones time for this fantastic read!! I definitely really liked every bit of it and I
    have you book-marked to check out new information on your site.

  2. I think this is among the most significant info for me.
    And i’m glad reading your article. But should remark on some general things, The site style is perfect, the articles is really excellent : D.

    Good job, cheers

  3. Today, I went to the beachfront with my kids. I found a sea shell and gave it to my 4
    year old daughter and said “You can hear the ocean if you put this to your ear.” She put the shell
    to her ear and screamed. There was a hermit crab inside and it pinched
    her ear. She never wants to go back! LoL I know this is entirely off topic but I had to tell someone!

  4. Fantastic beat ! I would like to apprentice while you amend your site, how
    can i subscribe for a weblog website? The account helped me a applicable
    deal. I have been tiny bit familiar of this your broadcast provided vivid transparent
    idea

  5. I’m impressed, I have to admit. Seldom do I encounter a blog that’s equally educative and engaging, and without a doubt, you have
    hit the nail on the head. The problem is an issue that too few people are speaking intelligently about.
    I’m very happy that I found this in my search for something concerning
    this.

  6. I’m extremely impressed together with your writing skills
    as smartly as with the structure for your weblog.
    Is that this a paid subject matter or did you modify it your self?
    Anyway stay up the nice high quality writing, it’s rare to look a nice blog like this one
    nowadays..

  7. Hi just wanted to give you a brief heads up and let you know a few
    of the pictures aren’t loading correctly. I’m not sure why but I think its a linking
    issue. I’ve tried it in two different internet browsers and both show
    the same results.

  8. Keren sekali ulasannya! Indonesia memang memiliki destinasi wisata yang sangat
    luar biasa. Saya sangat setuju bahwa Pesona Alam Indonesia adalah keindahan yang tak tergantikan, mulai dari
    gunung hingga pantainya. Syukran sudah berbagi informasi
    ini, sangat membantu saya merencanakan liburan berikutnya.
    Jangan lupa kunjungi Wisata Alam Indonesia
    yang lainnya juga! Wisata Alam Indonesia

  9. Hello, i read your blog from time to time and i own a similar one and i was just wondering if you
    get a lot of spam remarks? If so how do you prevent it, any plugin or anything you can advise?
    I get so much lately it’s driving me crazy so any
    support is very much appreciated.

  10. Unquestionably consider that which you stated.

    Your favorite reason appeared to be on the internet the simplest
    thing to take note of. I say to you, I definitely get irked
    while other folks think about concerns that
    they just do not recognise about. You managed to hit the nail
    upon the top as smartly as outlined out the whole thing without having side-effects , people can take
    a signal. Will probably be back to get more. Thanks

  11. Hmm it appears like your site ate my first comment (it was super long)
    so I guess I’ll just sum it up what I wrote and say,
    I’m thoroughly enjoying your blog. I too am
    an aspiring blog writer but I’m still new to the whole thing.
    Do you have any suggestions for newbie blog writers?

    I’d certainly appreciate it.

  12. It is the best time to make some plans for the future and
    it is time to be happy. I’ve read this post and if I could I desire
    to suggest you some interesting things or advice.

    Perhaps you could write next articles referring to this article.
    I wish to read more things about it!

  13. This is very fascinating, You are a very professional blogger.
    I’ve joined your rss feed and stay up for in quest of extra of your great post.
    Also, I have shared your website in my social networks

  14. Hello There. I found your blog using msn. This is an extremely well written article.
    I’ll be sure to bookmark it and return to read more of your useful info.

    Thanks for the post. I will definitely comeback.

  15. Do you have a spam problem on this site; I also am a blogger, and I was wondering your situation; many of us have created
    some nice procedures and we are looking to swap techniques with
    others, why not shoot me an email if interested.

  16. Hey there! I know this is kinda off topic but I was wondering which blog platform are you using
    for this website? I’m getting sick and tired of WordPress because I’ve had issues with hackers and I’m looking
    at alternatives for another platform. I would be
    great if you could point me in the direction of a good platform.

  17. Fantastic goods from you, man. I have understand your stuff previous to and
    you are just extremely magnificent. I actually
    like what you’ve acquired here, certainly like what you’re saying and
    the way in which you say it. You make it enjoyable
    and you still care for to keep it sensible.
    I cant wait to read much more from you. This is
    actually a wonderful site.

  18. Pretty section of content. I just stumbled upon your web site and in accession capital to assert that I acquire in fact
    enjoyed account your blog posts. Any way I’ll be subscribing to
    your feeds and even I achievement you access consistently rapidly.

  19. Thank you for any other informative blog. Where else may just I am getting that type of information written in such an ideal means?
    I’ve a mission that I’m simply now running on, and
    I have been at the look out for such information.

  20. Greetings, I do believe your site could possibly be having web browser
    compatibility issues. Whenever I take a look at your
    site in Safari, it looks fine however, when opening in IE, it
    has some overlapping issues. I simply wanted to give you a quick heads up!
    Other than that, great site!

  21. Attractive section of content. I just stumbled upon your site and in accession capital to assert that I get in fact enjoyed account your blog posts.
    Any way I’ll be subscribing to your feeds and even I achievement you access consistently rapidly.

  22. free fire max diamond top up, free fire india top up, codashop free fire
    top up, free fire diamond top up, free fire top up, garena free
    fire top
    up, free fire max top up, top up free fire max, top up free fire, top-up
    garena free fire, free fire diamonds top up, garena ff diamond top up,
    garena free fire max top up, top up ff max, free fire diamond shop,
    garena free fire top up diamonds, free fire top
    up offer, free fire
    diamond buy, ff diamond top up, ff diamonds top up, free fire diamonds
    buy, free fire id top up, free fire account top up, free fire max top up
    center, ff max top-up, ff top up, garena topup free fire,
    free fire
    top-up, free fire top up website in india, free fire top up codashop,
    garena top up center ff, free fire top up diamonds,
    free fire top up
    diamond, garena diamond top up free fire, top up diamond free fire
    codashop, double diamond top up codashop, free fire top up centre,
    free
    fire top up center, codashop free fire max paytm, diamonds free fire top
    up, diamond free fire top up, free fire special airdrop top up online,
    top up free fire diamond, top up free fire diamonds,
    codashop com free
    fire, garena free fire max top up center, garena free fire topup, free
    fire diamond recharge, diamond top-up free fire, free fire diamond top
    up app, free fire diamond top up site, garena free fire diamond top
    up,
    free fire diamond top up website, monthly membership in free fire, free
    fire garena top up, codashop ff top up, free
    fire top-up website, top up
    in free fire, garena free fire max diamond top up, garena free fire max
    diamonds top up, free fire diamonds top up app, free fire double diamond
    top up codashop, free fire diamond purchase, free fire top up india,
    winzo free fire diamond top up, free fire diamonds purchase, diamond top
    up in free fire, codashop free fire diamond india, free
    fire top up app,
    free fire topup, shop garena sg diamond, shop garena sg
    diamonds,
    freefire topup discount, top up garena free fire max, shop garena free
    fire diamond, freefire top up, top up game free fire, top up game free
    fire max, free fire online top up, free fire paytm top up, free
    fire top
    up paytm, free fire diamond topup, top up for free
    fire, free fire top
    up shop, free fire top up website, garena top up centre
    free fire,
    garena ff id top up, garena top up diamond, free fire game top up, free
    fire top up offers, free fire diamond store, coda shop
    diamond ff, free
    fire top up link, free fire top up live, free fire top up websites, top
    up app for free fire, top up app for free fire max, free fire top up
    recharge, free fire top ups, online free fire top up, online free fire
    top up max, free fire top up apps, garena free fire top up website,
    free
    fire airdrop top up online, free fire monthly membership top up,
    free
    fire diamond top up karo, diamond top up ff, seagm free
    fire, free fire
    diamond top up paytm, free fire top up upi, free fire official top up,
    top up website free fire, ggtopup free fire, seagm free fire top up,
    diamond top up website, ff top up codashop, free fire diamond top up
    garena, codashop free fire double diamond, free fire uid top up, free
    fire uid top up india, free fire uid top up online, best ff top up site,
    best free fire top up site, best free fire top up website, cheap diamond
    top up website, instant free fire top up, instant ff top up, buy free
    fire diamonds, purchase free fire diamonds, cheap free fire
    diamonds,
    cheapest free fire top up, affordable ff diamonds, trusted free fire top
    up, secure free fire top up, official free fire top up, free fire
    recharge, ff recharge, free fire recharge online, free fire recharge
    india, free fire recharge upi, free fire recharge paytm,
    free fire
    recharge phonepe, free fire recharge google pay, free fire recharge
    website, free fire recharge app, instant diamond top up, instant diamond
    delivery, free fire digital top up, online diamond purchase, free fire
    booyah pass, buy booyah pass, free fire weekly membership, buy
    weekly
    membership, free fire evo access, evo access top up, free fire level up
    pass, premium diamond top up, gaming recharge website,
    free fire gift
    card, ff gift card, free fire voucher, ff voucher, free fire online
    store, free fire recharge portal, ff recharge portal, 100 diamond top
    up, 310 diamond top up, 520 diamond top up, 1060 diamond top up,
    2180
    diamond top up, 5600 diamond top up, buy free fire max diamonds, instant
    free fire max top up, free fire max recharge, free fire max recharge
    online, ff max recharge, ff max diamonds, trusted diamond seller,
    verified gaming recharge, 24×7 free fire top up, fast ff recharge, quic k
    free fire recharge
    , DOUBLE DIAMOND TOP UP, double diamonds top up, games kharido, game kharido, top up free fire,
    fre fire top-up, top up free fire, free fire game top up

  23. This is the perfect web site for anybody who wishes to find out
    about this topic. You understand so much its almost hard to argue with you (not that I really would want to…HaHa).
    You definitely put a brand new spin on a subject that has
    been written about for many years. Wonderful stuff, just excellent!

  24. Thank you for the good writeup. It actually used
    to be a leisure account it. Look complicated to more delivered agreeable from you!
    By the way, how can we be in contact?

    Look at my site Suzanna

  25. Hey there would you mind letting me know which webhost you’re working with?
    I’ve loaded your blog in 3 completely different web browsers and I must say this blog loads
    a lot quicker then most. Can you suggest a good web hosting provider at a reasonable price?
    Cheers, I appreciate it!

  26. Hi! I’m at work surfing around your blog from my new apple iphone!

    Just wanted to say I love reading through your blog and look forward to all your posts!
    Keep up the fantastic work!

  27. It’s the best time to make a few plans for the future and it is time to be happy.
    I’ve read this post and if I may just I desire to suggest you some interesting
    issues or advice. Perhaps you can write next articles relating to this article.
    I desire to learn even more things about it!

  28. Hey there exceptional blog! Does running a blog similar to this require
    a large amount of work? I have no expertise in coding but
    I had been hoping to start my own blog in the near future.

    Anyways, should you have any ideas or tips for new blog owners please share.
    I understand this is off topic but I simply needed to ask.
    Thanks a lot!

  29. It is the best time to make some plans for the long run and it’s time to
    be happy. I have learn this put up and if I may I desire to suggest you some interesting
    issues or advice. Maybe you can write next articles relating
    to this article. I want to read even more things about it!

  30. Today, I went to the beach front with my kids. I found a sea shell and gave it to my 4
    year old daughter and said “You can hear the ocean if you put this to your ear.” She placed the shell to her ear and screamed.

    There was a hermit crab inside and it pinched her ear. She
    never wants to go back! LoL I know this is totally off topic but I had to
    tell someone!

  31. Hello, I think your blog might be having browser compatibility issues.
    When I look at your website in Opera, it looks fine but when opening in Internet Explorer, it has some
    overlapping. I just wanted to give you a quick heads up!
    Other then that, fantastic blog!

  32. Hey there! I know this is kind of off topic but I was wondering which blog platform are you using
    for this site? I’m getting sick and tired of WordPress because I’ve
    had issues with hackers and I’m looking at options for another platform.

    I would be great if you could point me in the direction of a good platform.

  33. Hi! I’ve been following your site for a while now and finally got the courage to go ahead and give you
    a shout out from Atascocita Texas! Just wanted to mention keep up the fantastic work!

  34. Hmm is anyone else experiencing problems with the pictures on this blog loading?
    I’m trying to determine if its a problem on my end or if it’s the
    blog. Any feedback would be greatly appreciated.

  35. Hello just wanted to give you a brief heads up and let
    you know a few of the pictures aren’t loading properly.
    I’m not sure why but I think its a linking issue. I’ve tried it in two different browsers
    and both show the same results.

  36. Having read this I thought it was really enlightening.
    I appreciate you spending some time and effort to put this content
    together. I once again find myself personally spending a significant amount of time both reading and posting comments.
    But so what, it was still worth it!

  37. My developer is trying to convince me to move to .net from
    PHP. I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress
    on numerous websites for about a year and am worried about
    switching to another platform. I have heard good things about blogengine.net.

    Is there a way I can import all my wordpress content into it?
    Any help would be really appreciated!

  38. I know this if off topic but I’m looking into starting my own weblog and was curious what
    all is needed to get setup? I’m assuming having a blog like
    yours would cost a pretty penny? I’m not very web smart
    so I’m not 100% sure. Any suggestions or advice would be greatly
    appreciated. Appreciate it

  39. What i don’t realize is in reality how you are no longer actually much more well-liked
    than you might be now. You are very intelligent.
    You realize thus significantly with regards to this subject, produced me in my opinion believe it from
    so many varied angles. Its like men and women are not fascinated
    unless it’s one thing to do with Lady gaga!
    Your own stuffs great. At all times handle it up!

  40. Hey! Would you mind if I share your blog with my myspace group?
    There’s a lot of people that I think would really appreciate your content.
    Please let me know. Thanks

  41. Great beat ! I wish to apprentice at the same time as you
    amend your web site, how could i subscribe for a weblog web site?
    The account helped me a applicable deal. I have been a little bit familiar of this your broadcast provided brilliant clear concept

  42. I’m truly enjoying the design and layout of your website.
    It’s a very easy on the eyes which makes it much
    more enjoyable for me to come here and visit more
    often. Did you hire out a designer to create your theme?
    Exceptional work!

  43. Have you ever thought about creating an e-book or guest authoring on other sites?
    I have a blog based upon on the same ideas you discuss and would love to have you share
    some stories/information. I know my audience would appreciate your work.

    If you’re even remotely interested, feel free to send me an e-mail.

  44. “Every practice listed in the National Orthodontic Registry is cross-referenced against the NPPES NPI Registry, the U.S. Department of Health & Human Services’ official provider database,”
    the registry states in its verification documentation .
    Most commercial directories rely on self-reported information instead.

  45. Hi! This is my first visit to your blog! We are a group of volunteers and starting a new project in a
    community in the same niche. Your blog provided us beneficial information to work
    on. You have done a extraordinary job!

  46. Reading through this post reminded me how critical it is to act fast when acre damage occurs.
    Experienced repair crews understand how to assess
    acre damage and deliver solutions that actually hold up. Emergency
    acre repair professionals who communicate clearly with clients tend to
    deliver far better overall outcomes. I would strongly
    recommend checking out emergencyacrepair1.info for anyone dealing with urgent property or land repair issues.

  47. Hi excellent website! Does running a blog such as this take a lot of work?
    I’ve very little expertise in computer programming however I was hoping to start my own blog in the
    near future. Anyways, if you have any ideas or techniques for new blog owners please share.
    I know this is off topic however I just had to ask. Kudos!

  48. This is really attention-grabbing, You’re a very
    skilled blogger. I’ve joined your feed and look
    ahead to in search of more of your great post. Additionally, I have shared your web site in my social networks

  49. Hey There. I discovered your blog using msn. That is a really neatly written article.
    I will make sure to bookmark it and come back to learn extra of your useful information. Thank you for the post.
    I will definitely comeback.

  50. This design is wicked! You certainly know how to keep a reader amused.
    Between your wit and your videos, I was almost moved to start my
    own blog (well, almost…HaHa!) Wonderful job. I really enjoyed what you had to
    say, and more than that, how you presented
    it. Too cool!

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Read More

SOLID Principles

Table of Contents Hide Single-responsibility PrincipleOpen/Closed Principle (OCP)Liskov Substitution Principle (LSP)Interface Segregation Principle (ISP)Dependency Inversion Principle (DIP)Advantages of…
Read More

20 Laravel Eloquent Tips and Tricks (P1)

Eloquent ORM được sủ dụng rất nhiều trong 1 project Laravel, tuy nhiên để sử dụng được tối đa những gì Laravel cung cấp thì không phải ai cũng biết. Trong bài viết này mình sẽ chỉ cho các bạn một vài thủ thuật, hi vọng sẽ giúp ích cho các bạn trong một vài trường hợp cụ thể.