Somebody comments the keyword and the notification reaches our server. In under two and a half seconds the engine checks the rule, writes the row for the send before anything goes out, and spends the single private reply Meta allows per comment. Everything after that, the follow gate or the request for an address, happens inside the conversation that person opened.
Two and a half seconds to answer
The engine does not run whenever it feels like it. It runs inside the notification that arrives when somebody comments, and that notification has to be acknowledged quickly or it gets retried. The budget we give ourselves is two and a half seconds, counted from the top and not from our own part of it, because by then the inbox has already stored the comment as one more message.
Two decisions follow from that, and they shape everything else. The first is that the checks run in order of cost: first everything that can be known without leaving the database, is the rule still active, does the workspace hold the module and is it unlocked, is the comment recent, is the keyword there; and only at the end anything that requires talking to the network. An expensive check placed first is one that, on the day the network is slow, spends the whole budget before deciding anything.
The second is that the row for the send is written before any outbound call. That is not bookkeeping. A send that goes out and leaves no record is indistinguishable from one that never went, and with a single private reply per comment that ambiguity is paid for by sending twice or not at all. A row left in the first state is, on its own, evidence that the engine ran out of time before its first call. It is a line somebody can read instead of a silence.
What counts as the keyword
It looks like the trivial part and it is where expectations break most often. There are three ways to compare, and they are three different products:
- Whole word, the default, because it behaves the way somebody who typed PRICE expects: it matches price on its own and inside a question, and it never matches priceless.
- Contains, a plain substring, which is what a hashtag campaign wants.
- Exact, the whole message and nothing else, for when the keyword works like a password.
Before anything is compared the text is normalised: lowercased, spaces collapsed, accents stripped. So a word written with an accent and the same word written without one are the same word here, which is the right answer for what is being compared: a comment thread is typed on phones and half of it carries no accents at all, and a rule that fired for one spelling and not the other would look broken to whoever set it. The original text is stored exactly as it was written.
And one rule admits no nuance: exclusions always win. A rule set to answer every comment still has to be able to stay out of not interested or this is a scam. An exclusion you could bypass by flipping one switch would be a decision the user made and the product ignored.
One private reply per comment
Meta allows exactly one private reply per comment, within the following seven days, and a call that fails spends it anyway. That sentence is the origin of half the architecture.
It is why the send slot is reserved before anything goes out, against an hourly ceiling per account, rather than counted afterwards. Counting afterwards means discovering the limit by being throttled, and by then the attempt is already lost. With the reservation first, a send that would cross the line never happens and is recorded as paced rather than failed, which is a line with a cause on it instead of an error with none.
It is also why a slot spent on a failed send is not given back. A call that failed after leaving here may well have arrived, with the response lost on the way, and returning the slot would hand it to a second send while the first is possibly already delivered. The cost is one unused slot for the rest of that hour; the mistake it avoids is the only one this mechanism exists for.
And it is why a comment older than seven days is not attempted at all: that would spend the call on a guaranteed error. A new comment inside an old thread, on the other hand, is a comment written today and is treated as one.
The steps in between, in order
Between the keyword matching and the link going out there can be up to three optional steps, always in this order.
| Step | What it does | Where it can stop |
|---|---|---|
| Opening | A short message asking for a tap to open the conversation | If nobody answers, the row waits |
| Follow gate | Asks the person to follow and reads their reply | Three attempts and it stops |
| Asks for an address and recognises one in the reply | Two attempts and the link goes anyway | |
| Delivery | The message carrying your short link | This is the end of the run |
Every message the person writes asks again where their row had got to and moves it on from there, with one single function deciding the next step for both ways in. That the email step gives up on the second ask is a business decision written into the code: a lead is worth more than an address, and somebody who has replied twice without giving one has answered the question in their own way.
The follow gate asks, it does not look up
This is the part most often misread when it gets told quickly. Instagram only answers the question of whether somebody follows you once that person has written to the account, so for a commenter you have never heard from the answer is not they do not follow you, it is this cannot be known. That is the normal case, not the exception.
Which is why the gate asks. The message carries the question, the person answers, and that answer is the confirmation. It is not a lookup against the network, because for this case that lookup does not exist, and selling it as one would be selling a fact that comes back empty almost every time. If the person never answers, the conversation stays where it is: there are three attempts in total and then nothing, which is the difference between a gate and a bot that argues.
There is a technical detail with product consequences. Since late August 2026 Instagram refuses buttons on a message to somebody who does not follow the account, and the refusal spends the comment's only private reply. So the button rides only when the network has confirmed that the person follows you, or when the conversation is already open because they wrote first; everybody else gets the link as plain text on its own line. A control that looks slightly nicer is not worth a person you can no longer reach. How all of this is set up from the screen is on the Auto DM page, and the Instagram path in detail is in the Instagram Auto DM guide.
Everything in this article happens in one place in GoFeed.
Try it freeThe short link and the click
Every send carries its own short link, shaped as a slash, an r and a ten character code, and served by this very site. Not one per rule and not one per destination: one per delivery.
That is what makes the clicks countable without following anybody around. If an address was handed to exactly one person, this send was opened is true with no cookie, no IP and no browser fingerprint. What it costs is a row per delivery, swept on its own after a while once the day's summary holds the number.
Two small decisions on that route are worth knowing. The redirect is temporary rather than permanent, because a permanent one gets cached by the browser and then the click happens and is never counted. And the route is excluded in the robots file, not for privacy but because it is not a page: every request is a click, and a crawler having a look would be a click nobody made.
What the engine does not do
It does not write for you. The text is the text you wrote, with variations if you set them, and nothing drafts a message on your behalf.
It does not work on every network. Instagram and Facebook, which are the accounts whose comments and messages arrive here, and the triggers are a comment, a story reply, which is Instagram's, and a direct message. If what you want is to organise what already lands in the inbox, that is a different job and it is covered in how to manage your DMs.
And it does not retry on its own. A conversation left half finished stays half finished, and it still counts as a contact reached, because the first message went out. Contacts are the one soft quota in the product: nothing stops when the ceiling arrives, the entry tier carries one and the tiers above it do not, and whatever goes past it is billed per contact instead of being refused. The reasoning is in why we do not charge per contact, and what each tier carries is on the pricing page.