Open Source Maintenance from Indonesia: The UTC+7 Timezone Tax

Photo by Shixart1985 via Wikimedia Commons (CC BY 2.0)
Indonesia appears on the supported-regions list in GitHub's own Sponsors documentation, which I read on 4 September 2026. Anyone in any region can sponsor a maintainer, but you must reside in a supported region to receive funds. Region lists change without notice, so check the docs page yourself on the day you sign up rather than trusting a blog post.
Around 21:00 WIB, which is 14:00 UTC. That single hour is 09:00 or 10:00 on the US East Coast and 15:00 or 16:00 in Central Europe, so a reply written then lands inside somebody's working day. Triaging at 07:00 WIB is midnight UTC and reaches almost nobody, which makes the next round trip take an extra day.
Because latency dominates, not effort. Western Indonesia Time is UTC+07:00 and Indonesia observes no daylight saving, so you sit eleven or twelve hours from most US contributors. A clarifying question that costs minutes inside one timezone costs a full day across that gap, and three sequential questions cost three days.
Move the filtering to intake instead of the reply. GitHub issue forms let you require a version field, a minimal reproduction and a pre-filing checklist before the issue can be submitted at all. Turning blank issues off and adding a contact link to Discussions moves usage questions out of a queue that implies a same-day answer.
Usually no, and the honest way to decline is a non-goals list in the README written before your first release. Accepting code you do not run means owning something you cannot test against a real workload, in a timezone where each question about it costs a day. Point at the documented scope so the decline is about criteria, not taste.

Photo by Shixart1985 via Wikimedia Commons (CC BY 2.0)
Key Takeaway
Maintaining an open source package from Indonesia means every clarifying question costs a day, not an hour, because UTC+7 sits eleven or twelve hours from most contributors. Batch triage into one evening window, reject unactionable reports with issue forms, state a response time in the README, and keep the scope small enough to refuse features.
A bug report on my npm package landed at 14:00 New York time. In Jakarta that is one in the morning. I read it the following evening, asked which version they were on, and the answer arrived while I was asleep again. The exchange was perhaps two hours of real work and it took forty-four hours of wall clock.
I maintain hierarchical-approval, a small TypeScript package for ERP approval chains, from UTC+7 alongside a full-time job. This post is the operating procedure I ended up with: what the timezone gap actually costs, the one hour of the day worth spending on triage, the intake that stops unactionable reports at the door, the scope statement that makes a decline quick, and the funding question every Indonesian maintainer asks and almost nobody answers with a citation.
Western Indonesia Time is UTC+07:00 and no part of Indonesia observes daylight saving, which has a consequence nobody warns you about: the gap between you and your contributors changes twice a year because their clocks move, not yours. Against the US East Coast that gap is eleven or twelve hours depending on the month. The practical effect is that latency, not effort, is what makes maintenance feel heavy. Answering an issue takes ten minutes. Closing it takes two days.
| Contributor's zone | Their 09:00 to 17:00, in WIB | What that leaves you |
|---|---|---|
| US Pacific, UTC-7 in summer | 23:00 to 07:00 the next day | Nothing usable. Their working day is your night, all year |
| US Eastern, UTC-4 in summer | 20:00 to 04:00 the next day | Three hours after work, 20:00 to 23:00 |
| United Kingdom, UTC+1 in summer | 15:00 to 23:00 | Four hours after work, 19:00 to 23:00 |
| Central Europe, UTC+2 in summer | 14:00 to 22:00 | Three hours after work, 19:00 to 22:00 |
Read the last column downwards and the finding is sitting there: one evening covers Europe and the US East Coast, and never covers the US West Coast at all. So I stopped trying to be reachable by everyone. A contributor in California gets an answer the following evening, and the README says so rather than leaving them to work it out from the timestamps.
The hour that matters is 21:00 WIB. That is 14:00 UTC, which lands at 09:00 or 10:00 in New York and 15:00 or 16:00 in Berlin, depending on which side of their daylight saving switch the year is on. A reply written then arrives inside somebody's working day instead of at the bottom of tomorrow's inbox, so the next hop happens the same day rather than the next one. Triaging before work at 07:00 WIB felt more disciplined and was strictly worse: 07:00 WIB is midnight UTC, the middle of nobody's day.
# One pass, 21:00 WIB. That is 14:00 UTC, which is 09:00 or 10:00 in
# New York and 15:00 or 16:00 in Berlin, whichever side of their DST
# switch the year is on. My clock never moves, so theirs is the one
# that changes the gap twice a year.
# Oldest first: the oldest report has waited across the gap longest.
# gh issue list has no --sort flag; sorting is a search qualifier.
gh issue list --repo matthews-wong/hierarchical-approval \
--state open --label needs-triage \
--search "sort:created-asc" \
--limit 20 \
--json number,title,author,createdAt,comments
# The pile that is genuinely mine: I asked a question and nobody came back.
# Anything here is a candidate to close, not a debt I still owe.
gh issue list --repo matthews-wong/hierarchical-approval \
--state open \
--search "label:needs-info sort:updated-asc updated:<2026-09-08" \
--json number,title,updatedAt
# Thirty minutes, then the laptop closes. The queue is not the job.The pass is two queries and thirty minutes. The first is everything untouched, oldest first, because the oldest report has been waiting across the gap the longest. The second is the pile I already answered where nobody came back, and that pile is a closing list rather than a debt I still owe. Note that gh issue list has no sort flag of its own; the ordering rides in the search query as a qualifier.
The highest-leverage habit I have is refusing to ask questions one at a time. Inside a single timezone a follow-up costs a few minutes. Across eleven hours it costs a day, and three questions asked in sequence cost three days. So every reply gets written as though it is the only one I am allowed to send.
Saved replies carry the questions I ask nearly every week. The one that earns its place is the reproduction request, because it is long enough that I would otherwise write a shorter and worse version of it at half past ten at night.

The cheapest round trip is the one that never happens, and the place to prevent it is intake. GitHub's issue forms replace the free-text box with a schema: markdown, input, textarea, dropdown, checkboxes and upload elements, each able to carry a required validation. A required version field on its own removed the most common first reply I used to write.
# .github/ISSUE_TEMPLATE/bug.yml
name: Bug report
description: The package does something the README says it should not
labels: ["needs-triage"]
body:
- type: input
id: version
attributes:
label: Package version
description: The exact version from your lockfile, not "latest"
placeholder: 3.3.0
validations:
required: true # this one field kills half of all round trips
- type: textarea
id: repro
attributes:
label: Minimal reproduction
description: The smallest snippet that fails, or a link to a repo
render: typescript # render is textarea-only in the form schema
validations:
required: true
- type: dropdown
id: runtime
attributes:
label: Runtime
options: [Node 20, Node 22, Bun, Browser]
validations:
required: true
- type: checkboxes
id: prechecks
attributes:
label: Before filing
options:
- label: I searched the closed issues
required: true
- label: I read the Scope section of the README
required: true
# .github/ISSUE_TEMPLATE/config.yml
# Blank issues are where unactionable reports come from. Turn them off and
# route the "how do I" traffic to Discussions, which nobody expects a
# same-day answer from.
blank_issues_enabled: false
contact_links:
- name: Question about usage
url: https://github.com/matthews-wong/hierarchical-approval/discussions
about: Ask here. Issues are for reproducible defects only.Two details matter more than the rest. The render key is textarea-only in the form schema, and setting it to typescript gets you a fenced code block instead of a wall of unindented text. And turning blank issues off in config.yml is the switch that actually changes what arrives, because the contact link beside it sends usage questions to Discussions, which nobody expects a same-day answer from.
Silence reads as abandonment, and from UTC+7 you generate a lot of it by accident. The Open Source Guides suggest telling people plainly what to expect, with wording along the lines of a response from a maintainer within seven days and an invitation to ping the thread after that. Writing my own version of that sentence into the README changed the tone of the issue tracker more than any speed improvement did.
The window I publish is three working days, which I can hit on a bad week rather than a good one. That is the entire trick. A promise you keep at your worst is worth more than one you keep when nothing else is happening, because the weeks that break your response time are precisely the weeks in which a stranger forms their opinion of the project.
Do not publish a response window you can only hit when the day job is quiet. The first time somebody waits nine days against a stated three, they conclude the project is unmaintained, and forking is far cheaper for them than another week of waiting. Under-promise, then close issues early.
GitHub Sponsors publishes a list of supported regions and Indonesia is on it. I opened the docs page on 4 September 2026 and read the list rather than repeating what a forum thread said in 2021, which is the only way this question is worth answering. Anyone in any region can sponsor, but you must reside in a supported region to receive funds. GitHub charges no fee on sponsorships from personal accounts, and up to 6 percent on sponsorships from organisation accounts.
That is the only part I will state as fact, because it is the part I verified. Open Collective is the other platform people name, and I am deliberately not stating its current position for an Indonesian individual, because I did not check it to the same standard. Verify your own eligibility on the day you sign up, including which currencies your account can actually receive. A region list published in a blog post, this one included, is a snapshot; platforms add and drop regions without telling anyone who wrote about them.
Set the sponsorship route up once, early, and then stop thinking about it. The failure mode is not that nobody sponsors you. It is building the package as though funding were coming, which quietly turns a hobby into an obligation with no deadline, no client and no agreed way to stop.
Every issue in the first pass gets one of three answers: close it now, ask one round of questions, or accept it. Which one it gets is decided by a section of the README written before the first release, not by how I feel at half past nine on a Tuesday. The Open Source Guides put the reasoning better than I can — a documented scope lets you say the contribution does not match the project's criteria rather than saying you do not like it, and that difference is why the decline takes a minute and the thread stays civil.
## Scope
This package resolves an approval-chain definition into an ordered list of
approvers. That is the whole job.
### Non-goals
These are decisions, not gaps. A pull request implementing one of them will
be closed with a link to this section, politely and quickly:
- Notification delivery. No email, no WhatsApp, no push. Bring a transport.
- A UI. There is no React component here and there will not be one.
- Persistence. The library never opens a database connection.
- Framework adapters beyond the two that exist. The wrapper is 40 lines.
### Response time
I read issues once a day, in the evening, UTC+7. Expect a first reply within
three working days. If a week goes by in silence, ping the thread. You are
not being ignored and the project is not abandoned. It has one maintainer
and he has a day job.The non-goals list is the part people skip and the part that does the work. Accepting a feature you will never run yourself is exactly how a small package becomes unmaintainable: you now own code you cannot test against a real workload, in a timezone where every question about it costs a day. I would rather ship a package that does one thing and gets forked by whoever needs the second thing.
Write the non-goals list before the first release, while saying no still costs nothing. Adding it afterwards means retroactively closing issues that people have already invested in, and that is a genuinely unpleasant conversation to hold across an eleven-hour gap where each clarification costs another day.

Not money, in my case, and I would rather say that plainly than imply otherwise. What comes back is a portfolio a stranger can verify without believing anything I say about myself: a repository with a legible commit history, issues answered in public, and declines written politely enough that the thread is still worth reading years later. That is much harder to fabricate than a line on a CV, and it travels further.
The second return is review discipline. Reading somebody else's code at nine in the evening, without the context they have and without the ability to tap them on the shoulder, teaches you exactly what a pull request must contain to be reviewable — and I write my day-job pull requests differently because of it. That is a real transfer of skill and it is the honest argument for doing any of this. Unpaid work is not good because it is open source; it is worth doing when it teaches you something the paid work does not.
The rule I would hand my own past self is short. Decide what the package will never do before you decide what it will. Publish a response time you can hit in your worst week, not your best. Put your single triage window at the hour that falls inside somebody else's working day. Everything else about maintaining from UTC+7 is downstream of those three decisions, and none of them costs anything except the discipline to make them early.
Sources and further reading