US banks pay serious money for new checking customers. Chase, Wells Fargo, Bank of America, U.S. Bank, Citi, SoFi and dozens of regional and online banks routinely offer $200 to $450 for a personal checking account, $300 to $1,000 for a business account, and tiered “bring big money” offers that go up to $2,000+. The bank expects you to stay for ten years and take out a mortgage. You are going to stay for six months and take the bonus.

That is bank bonus churning: open an account, hit the requirement (usually a direct deposit or a balance), collect the bonus, wait out the early-closure window, close, repeat with the next bank. Then, once the bank’s cooldown expires (Chase: two years), do it again.

It is fully legal. It is also a beat-the-system play, because the requirement banks care about most, “direct deposit”, is defined loosely enough that you can satisfy it with one paycheck rotated across banks or with ACH pushes from another bank or brokerage that the receiving bank codes as payroll. The banks know people do this. Some shrug, some close accounts and blacklist you. This guide covers how it actually works, a Python tracker so you never miss a deadline (missing one is how people lose money here), real earnings, and the real risks.

Who this works for (read first)

  • US residents with an SSN and a US address. Every one of these accounts runs KYC plus ChexSystems/Early Warning checks. There is no VPN workaround, and lying on a bank application is federal bank fraud. Do not try it from abroad.
  • People with some cash float. You can start with $1,000-$5,000. The big tiers need $15,000-$200,000 sitting in an account for 60-90 days.
  • Organised people. The money is in not screwing up dates. If you would forget to move a deposit, you will forfeit bonuses and eat monthly fees.

If you are outside the US: the same playbook exists in smaller form elsewhere (UK bank switching offers via CASS, for example, which regularly pay £150-£200), but this article is US-specific.

How the money works

A typical offer looks like this (representative of Chase Total Checking offers running in 2026; earlier versions paid $300 for $500 of direct deposits; offers change, always read the current terms):

  • Bonus: $400
  • Requirement: open the account with the coupon, receive direct deposits totaling $1,000+ within 90 days
  • Payout: within 15 days after the requirement is met
  • Clawback: if you close within 6 months, Chase can deduct the bonus
  • Fee: $15/month, waived with $500+ in monthly direct deposits
  • Cooldown: one checking bonus every two years

So: $1,000 of your own paycheck lands in Chase, you move it right back out, and a few weeks later you have $400. That is a 40% return on money that left the account the same day. The only real costs are the time, a ChexSystems inquiry, and the opportunity cost of any balance you have to park.

The rotation trick

Most “direct deposit” requirements are small ($500-$2,000) and most employers let you split payroll across 2-5 accounts, or change the destination every pay period. One $4,000/month paycheck can feed four bank bonuses at once:

Bank (example offer)DD neededWindowBonus
Chase Total Checking$1,000 total90 days$400
Wells Fargo Everyday Checking$1,000 total90 days$325
Bank of America Advantage Plus$2,000 / $5,000 / $10,000 total90 days$100 / $300 / $500
SoFi Checking & Savings$1,000 / $5,000+25-day eval period$50 / $400

(These are 2026 offer structures; several have since expired or rotated. Check the live terms before you open anything.)

Pay period one: $1,000 to Chase, $1,000 to Wells, $2,000 to BofA. The money is yours the moment it lands, so you just transfer it back to your main bank. Three bonuses, about $825 ($400 + $325 + $100), from one month of pay that you never actually lost access to. Push more through BofA over the 90 days and that tier climbs to $300.

The “what counts as direct deposit” game

Here is the grey part. Banks define direct deposit as an ACH credit from an employer, payroll provider or government agency. In practice, the receiving bank’s system looks at the ACH transaction code and the company name, and many banks accept ACH pushes from other banks or brokerages as if they were payroll. Doctor of Credit maintains a crowdsourced list, “What Counts As A Direct Deposit”, with per-bank data points (for example, which banks accept a push from Fidelity, Schwab, Ally or a credit union). If your target bank accepts a push from an account you already have, you do not even need to touch your payroll.

This is not illegal: you are moving your own money with your own name on both ends. It can violate the spirit or letter of the offer terms, and banks are entitled to deny the bonus. Treat every data point as “worked for someone last month”, not a guarantee. If your payroll can split, use real payroll first. It always works.

What you need

ItemCostNotes
SSN, US address, government ID-Applications are in your real name only
Float$1,000-$5,000 to startMore unlocks business and tiered offers
Payroll that allows split depositsFreeAsk HR or check Gusto/ADP/Workday settings
Doctor of Credit (doctorofcredit.com) “Best Bank Account Bonuses” pageFreeUpdated list of live offers, the most useful page on the internet for this
r/churning and DoC comment threadsFreeData points on DD triggers, clawbacks, shutdowns
ChexSystems consumer reportFree (once a year by law)Request at chexsystems.com to see your inquiries and any negative record
A free high-yield savings accountFreePark float between bonuses so it earns ~3.5-4%
Python 3.10+FreeFor the tracker below
A spreadsheet or CSVFreeSource of truth for every account

No paid tools needed. Paid services exist (some churning trackers and newsletters charge $5-$15/month), but a CSV and 80 lines of Python does the job.

Step 1: Pull your ChexSystems report and freeze nothing yet

Go to chexsystems.com and request your free consumer disclosure. You want to know two things:

  1. You have no negative record. An unpaid overdraft from years ago will get you denied everywhere.
  2. How many inquiries you already have. Some banks (community consensus names Chase, Bank of America and Wells Fargo among the more sensitive ones) deny applicants with lots of recent ChexSystems or Early Warning inquiries. The common r/churning rule of thumb is to keep it to a handful of new checking accounts every few months and open the “sensitive” banks first.

Also note which banks do a hard credit pull for checking. Most do soft pulls, a few do hard pulls; Doctor of Credit lists the pull type on each offer. Hard pulls matter if you are also churning credit cards or about to apply for a mortgage.

Step 2: Build the CSV

Create bonuses.csv. One row per account. Dates in ISO format.

bank,bonus,opened,dd_required,dd_done,dd_window_days,payout_days,keep_open_days,cooldown_days,bonus_paid,fee_waiver
Chase Total Checking,400,2026-09-02,1000,1000,90,15,180,730,yes,$500 DD/month
Wells Fargo Everyday,325,2026-09-10,1000,400,90,30,180,365,no,$500 DD/month or $500 balance
BofA Advantage Plus,300,2026-10-01,5000,0,90,60,90,365,no,$250 DD/month or $1500 balance
Huntington Perks,400,,500,0,90,14,90,0,no,$5000 total balance

Leave opened empty for offers you plan to open later. keep_open_days is the clawback or early-closure window from the terms. cooldown_days is how long before you can earn a bonus from that bank again (check the terms; Chase says two years, many banks say “no bonus if you had an account in the last 12 months”). If the terms say nothing, put 0 and assume you are one-and-done.

Step 3: The tracker

Save as bonus_tracker.py. Standard library only.

#!/usr/bin/env python3
"""bonus_tracker.py - what to do today across all your bank bonuses."""
import csv
import sys
from datetime import date, timedelta

TODAY = date.today()
CSV_PATH = sys.argv[1] if len(sys.argv) > 1 else "bonuses.csv"
PAYCHECK = float(sys.argv[2]) if len(sys.argv) > 2 else 0  # next paycheck amount
INQUIRY_WARN = 6  # new checking accounts in 12 months before you slow down


def d(s):
    return date.fromisoformat(s.strip()) if s and s.strip() else None


rows = list(csv.DictReader(open(CSV_PATH, newline="")))
actions, needs, opened_12m = [], [], 0
earned = pending = 0.0

for r in rows:
    bank = r["bank"]
    bonus = float(r["bonus"])
    opened = d(r["opened"])
    if not opened:
        actions.append((999, f"QUEUED    {bank}: ${bonus:,.0f} offer, not opened yet"))
        continue
    if (TODAY - opened).days <= 365:
        opened_12m += 1

    dd_req, dd_done = float(r["dd_required"]), float(r["dd_done"] or 0)
    dd_deadline = opened + timedelta(days=int(r["dd_window_days"]))
    payout_by = dd_deadline + timedelta(days=int(r["payout_days"]))
    close_ok = opened + timedelta(days=int(r["keep_open_days"]))
    again = opened + timedelta(days=int(r["cooldown_days"])) if int(r["cooldown_days"]) else None
    paid = r["bonus_paid"].strip().lower() == "yes"
    left = (dd_deadline - TODAY).days

    if paid:
        earned += bonus
        if TODAY >= close_ok:
            msg = f"CLOSE OK  {bank}: past {r['keep_open_days']}-day window"
            if again:
                msg += f", bonus eligible again {again}"
            actions.append((500, msg))
        else:
            actions.append((400 + (close_ok - TODAY).days,
                            f"HOLD      {bank}: keep open until {close_ok}, fee waiver: {r['fee_waiver']}"))
        continue

    pending += bonus
    if dd_done < dd_req and left >= 0:
        short = dd_req - dd_done
        needs.append((left, bank, short))
        flag = "URGENT   " if left <= 14 else "DEPOSIT  "
        actions.append((left, f"{flag} {bank}: ${short:,.0f} DD still needed, {left} days left ({dd_deadline})"))
    elif dd_done < dd_req:
        actions.append((-1, f"MISSED    {bank}: DD window closed {dd_deadline}. Chat/call and ask for an extension"))
    elif TODAY > payout_by:
        actions.append((0, f"CHASE IT  {bank}: requirement met, bonus overdue since {payout_by}. Send secure message"))
    else:
        actions.append((300, f"WAITING   {bank}: requirement met, bonus due by {payout_by}"))

for _, line in sorted(actions):
    print(line)

print(f"\nEarned: ${earned:,.0f} | Pending: ${pending:,.0f} | Accounts opened last 12 months: {opened_12m}")
if opened_12m >= INQUIRY_WARN:
    print("WARNING: lots of recent openings. Expect denials at sensitive banks, slow down.")

# Split the next paycheck: most urgent requirement first
if PAYCHECK and needs:
    print(f"\nSuggested split for a ${PAYCHECK:,.0f} paycheck:")
    remaining = PAYCHECK
    for left, bank, short in sorted(needs):
        amt = min(short, remaining)
        if amt <= 0:
            break
        print(f"  ${amt:>8,.0f} -> {bank}  (deadline in {left} days)")
        remaining -= amt
    print(f"  ${remaining:>8,.0f} -> your main account")

Run it:

python3 bonus_tracker.py bonuses.csv 3200

Example output (run on 2026-10-21):

DEPOSIT   Wells Fargo Everyday: $600 DD still needed, 49 days left (2026-12-09)
DEPOSIT   BofA Advantage Plus: $5,000 DD still needed, 70 days left (2026-12-30)
HOLD      Chase Total Checking: keep open until 2027-03-01, fee waiver: $500 DD/month
QUEUED    Huntington Perks: $400 offer, not opened yet

Earned: $400 | Pending: $625 | Accounts opened last 12 months: 3

Suggested split for a $3,200 paycheck:
  $     600 -> Wells Fargo Everyday  (deadline in 49 days)
  $   2,600 -> BofA Advantage Plus  (deadline in 70 days)
  $       0 -> your main account

The split is a suggestion, not an order: you still need rent money, and since you can move funds straight back out, $0 to your main account just means one extra transfer.

Notice the Chase row: the bonus is paid, but it still needs $500/month in deposits until March or you pay $15/month in fees. Fee waivers are where churners quietly bleed money. Keep the fee_waiver column honest.

Run it every morning

Put it on cron and pipe it to yourself. Using a Telegram bot (create one with @BotFather, get your chat ID from @userinfobot):

crontab -e
# 8:00 every day
0 8 * * * cd /home/you/churn && python3 bonus_tracker.py bonuses.csv | curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d chat_id=$CHAT_ID --data-urlencode text@- > /dev/null

(Set TOKEN and CHAT_ID at the top of the crontab.) Update dd_done and bonus_paid whenever a deposit or bonus posts. Two minutes, a few times a week.

Step 4: Open accounts in the right order

  1. Sensitive big banks first while your ChexSystems inquiry count is low: Chase, Bank of America, Wells Fargo, Citi, U.S. Bank.
  2. Online banks and fintechs next (SoFi, Capital One 360 when it runs a bonus, etc.). Often instant approval, easy DD triggers.
  3. Regional banks in your state: Huntington, PNC, Fifth Third, KeyBank, TD and so on run $200-$600 offers constantly but only for residents of their footprint. DoC lets you filter by state.
  4. Business checking once you are comfortable. A sole proprietorship with your own SSN or a free EIN from irs.gov counts at many banks if you have real side income (freelancing, reselling). Chase Business Complete has run $300-$500 offers for keeping $2,000-$10,000 of new money for 60 days plus a few transactions. Do not invent a business you do not have; that is misrepresentation on a bank application.
  5. Tiered “new money” offers last, when you have the cash. Citi and others have run tiers up to $2,000 that require parking very large balances (six figures for the top tier) for 60-90 days. Do the math against a 4% savings account before you bite.

The float math on big tiers

Say an offer pays $700 for keeping $50,000 for 60 days. In a 4% high-yield savings account, $50,000 earns about $329 in 60 days. Your real profit is $700 - $329 = $371, still good, but not $700. Bonuses are taxed as interest either way, so the comparison is fair.

Honest cost breakdown

CostAmount
Tools (CSV, Python, cron, Telegram)$0
Monthly fees if you miss a waiver$5-$25 per account per month
Opportunity cost of parked float~4%/year on the parked amount, prorated
Early closure clawback if you close too earlythe whole bonus, sometimes plus a $25-$50 fee
Taxesbonuses are ordinary income, reported on 1099-INT (sometimes 1099-MISC). At a 22% federal bracket, $6,000 of bonuses costs ~$1,320 federal plus state
Time30-60 min per account to open, plus ~1 hour/week managing

Realistic earnings

Year one, one person, $3,000-$5,000 float, with payroll that can split:

  • 4-6 big-bank personal checking bonuses at ~$300 avg (there are only so many big banks, and each pays once per cooldown): $1,200-$1,800
  • 8-12 regional/online bank bonuses at $150-$400: $1,500-$3,500
  • 2-4 business checking bonuses at $300-$500, only if you have a real side business: $600-$2,000

Total: roughly $3,000-$7,000 pre-tax in year one, at maybe 80-120 hours of work. That is about $30-$60/hour before tax, legal, and repeatable as long as offers keep running. Expect a few bonuses to fail (denied applications, a DD that did not code, a missed deadline), so plan for the low end.

Scaling levers:

  • A spouse or partner doubles it. They open accounts in their own name with their own paycheck. That is completely legit. Opening accounts in someone else’s name that you control is not.
  • More capital unlocks the $1,000-$2,000 tiers. With $50k-$100k of float, gross bonuses can go well past year-one numbers, but your real profit is the bonus minus what that cash would earn anyway in a 4% savings account, which often cuts the headline in half.
  • Year two and beyond: cooldowns reset (Chase every 2 years, many banks after 12 months of no account). The list refills.

What it is not: $5k/month forever. Year one is the biggest because you clear the backlog of banks you have never used; after that you are limited by cooldowns and whatever new offers appear, so income drops and gets lumpy. Pair it with credit card sign-up bonuses (a separate game with hard pulls and minimum spend) if you want bigger numbers.

Risks: shutdowns, denials, clawbacks, taxes

Account closures and blacklisting. Banks can close your account for any reason, and some do close churners who move money in and out with no other activity. A few have reportedly banned people from future products. Chase is known for shutting down people who abuse it across many products. Losing one bank is not fatal; you lose that bank’s future bonuses.

Bonus denial. If your DD trigger is not coded as payroll, you met nothing. Before relying on a push, check recent data points. If it fails, you still have time to send a real payroll deposit, which is exactly why the tracker shows days left.

ChexSystems/Early Warning damage. Inquiries are not negative records, but a pile of them gets you auto-denied. The real danger is a negative record: closing an account with a negative balance or a fee you forgot can get reported and lock you out of banking for up to five years. Always zero out fees before closing.

Clawbacks. Close inside the window and the bank takes the bonus back. Some banks also claw back if you never maintain the “relationship” (e.g., the fee-waiver deposits). Read the terms.

Tax surprises. The bank sends a 1099 in January. Thirty bonuses means thirty forms. Report all of them; the IRS matches 1099-INT automatically.

Legal line. Everything above is legal if every application is truthful and in your own name. Fake employers, fake businesses, synthetic identities, or opening accounts as someone else is bank fraud (18 U.S.C. 1344), not “grey area”. Do not go there.

Reality check: what does not work

  • Assuming “any deposit” counts. Zelle, mobile check deposits and card funding almost never count as direct deposit.
  • Closing at day 89 because you got bored. Check keep_open_days. Many windows are 180 days.
  • Ignoring fees. Five accounts at $12/month each for four months is $240 gone.
  • Opening 10 accounts in a week. Inquiry spam gets you denied at the banks that pay the most. Pace it: 2-4 per month is plenty.
  • Trusting old offer screenshots. Offers change monthly. Check the bank’s own landing page and save a PDF of the terms the day you apply; it is your evidence if the bonus does not post.
  • Using a bonus link from a random Telegram channel. Some are referral links (fine), some are phishing. Go to the bank site directly or use DoC.
  • Not asking. When a bonus does not post, a polite secure message with the offer code and dates fixes it most of the time.

Start today

  1. Request your ChexSystems report (10 minutes).
  2. Open Doctor of Credit’s bank bonus list, filter by your state, and pick three offers: one big bank, one online bank, one regional.
  3. Check your payroll portal for split-deposit options.
  4. Create bonuses.csv, open the first account, and run the tracker.

Three accounts this month is roughly $600-$1,000 over the next two to four months (payouts land 2-8 weeks after you hit each requirement) for money that never really left your control. After that, it is a calendar problem, and the script solves the calendar.