<p dir="auto">This aims to implement <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="477236313" data-permission-text="Title is private" data-url="https://github.com/openstreetmap/openstreetmap-website/issues/2342" data-hovercard-type="issue" data-hovercard-url="/openstreetmap/openstreetmap-website/issues/2342/hovercard" href="https://github.com/openstreetmap/openstreetmap-website/issues/2342">#2342</a> by rate limiting edits.</p>
<p dir="auto">The limits work in a similar way to the changeset comment limits and are configurable with the defaults being a ramp up from 1000 changes per hour to 100000 per hour over the first week after a user starts editing. Users that are reported lose some allowance subject to a minimum that defaults to 100 edits per hour.</p>
<p dir="auto">The increase is non linear, increasing as the square of time elapsed by subject to the lower bound of the initial limit so that it starts to climb after about 18 hours as shown in this graph which shows hours on the X axis versus allowed edits per hour on the Y axis.</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/147741/278893700-a6c571e5-416f-4fe8-ac40-5fdc56002060.png"><img src="https://user-images.githubusercontent.com/147741/278893700-a6c571e5-416f-4fe8-ac40-5fdc56002060.png" alt="Screenshot from 2023-10-29 17-33-10" style="max-width: 100%;"></a></p>
<p dir="auto">Moderators have a separately configurable rate limit and this also introduces a new <code class="notranslate">importer</code> role that has a higher rate limit and which can be granted to accounts doing large imports/bulk edits.</p>
<p dir="auto">Obviously once this agreed cgimap will need work to respect the rate limits.</p>
<hr>
<h4>You can view, comment on, or merge this pull request online at:</h4>
<p> <a href='https://github.com/openstreetmap/openstreetmap-website/pull/4319'>https://github.com/openstreetmap/openstreetmap-website/pull/4319</a></p>
<h4>Commit Summary</h4>
<ul>
<li><a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/commits/3b1cc98cc9c48aac86ce1decbc744e783c203ee9" class="commit-link">3b1cc98</a> Add importer role that can be associated with higher rate limits</li>
<li><a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/commits/ca424810dfbaeb4e834ee71de6ac4f881ba38269" class="commit-link">ca42481</a> Add support for per-user limits on the rate changes can be made</li>
<li><a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/commits/23339e87229fade5bbfe0a94d8715d2fae94f324" class="commit-link">23339e8</a> Enforce rate limit for API calls which make changes</li>
<li><a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/commits/be185adc24b5813f6a006c5225531ab60ede9234" class="commit-link">be185ad</a> Add tests for API change rate limits</li>
</ul>
<h4 style="display: inline-block">File Changes </h4> <p style="display: inline-block">(<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files">23 files</a>)</p>
<ul>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-29beaabe278fd17493296745cecb67919f0906b47b8246ab770f5517615d9ef7">.rubocop_todo.yml</a>
(2)
</li>
<li>
<strong>A</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-c69a29101b419da19520be165f1800cab2cb3b413319b78ec3701a96b3fc8dd3">app/assets/images/roles/blank_importer.png</a>
(0)
</li>
<li>
<strong>A</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-3d43748cb7b10e6f1622e89987e0c83b9206ecd3c04320bddc9e232b168cd8cd">app/assets/images/roles/blank_importer.svg</a>
(65)
</li>
<li>
<strong>A</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-3934a6afd93043ddf1767733a66c4357ce8c5c4ad37783b8664533783c59c7c5">app/assets/images/roles/importer.png</a>
(0)
</li>
<li>
<strong>A</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-b0a2b69c9924295a2615b9368b28cc21a1021935915e0b6854f6e233ae0a8aa7">app/assets/images/roles/importer.svg</a>
(71)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-6726f8601cd22886963fb41888b55956cae4f8124aa12c701da77c3add44d94c">app/controllers/api/changesets_controller.rb</a>
(4)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-73fe5812764d31443ba0d43f028e68aa17963e92fe69d79f72957f5ac1a176b9">app/controllers/api/nodes_controller.rb</a>
(1)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-49b8b506dea5e046c47e71134ed6d1c4ca794559572895c26b1df469ceda868d">app/controllers/api/relations_controller.rb</a>
(1)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-eb50706672183bce46654d5a373c3df75906a65a3ae5055a16ba0d8d2005ca37">app/controllers/api/ways_controller.rb</a>
(1)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-380aab66173996fadff8576f19062da8bacc45be57582f15afb9fd46c411cbbf">app/controllers/api_controller.rb</a>
(7)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-9802ca3c9c4cf89904fd44bc114e35ebdf2c5dd3d5b645491e2b253e1afef29b">app/models/user.rb</a>
(22)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-1359c12a72797132da7f3f869920874f4b456a929bf75ad54a336fb87918b0bb">app/models/user_role.rb</a>
(2)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-0a387e55d510dce7686761db80135118e68a1ec66c125e3217a2871055fd8b36">config/initializers/migrate.rb</a>
(4)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-44438ce218f5287c58d0017f965d888715635d94280669896f75841fbd7b4cd7">config/locales/en.yml</a>
(3)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-e769bbb8c1ba3711c5403b424ed9c218ffafba7f1890ee394717196f28ff4540">config/settings.yml</a>
(6)
</li>
<li>
<strong>A</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-be3d40e1ed6febe91384e510ef82bc548b38a286a084a3526daa36a476d36da1">db/migrate/20231029151516_add_importer_role.rb</a>
(9)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-1dd5a8f580b9615769ddc19a64a98f455d9d20eb149c443f41d9d3c797d39b12">db/structure.sql</a>
(4)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-e95198c7f7744be3ce9857db36d2374538ca7d64caaf0f6f85865d6752563ee9">test/controllers/api/changesets_controller_test.rb</a>
(107)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-8a9c95ea5b86d8f52f78210e2ff053062ca9a234754dff890fb8aae45343ff4c">test/controllers/api/nodes_controller_test.rb</a>
(85)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-da8c6d0ce9e50a5d0d4517cb17a60cc0df2f286b573ea8132fd903ad8c227237">test/controllers/api/relations_controller_test.rb</a>
(111)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-ffae22d15753b266411f4613c7a78242cfd5a5ab95aad3484ce9728179a76334">test/controllers/api/ways_controller_test.rb</a>
(105)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-3cb894babbd387f02bde8eb4daf7ddb6f0a5207d0562af589dc59a5653092c04">test/factories/user.rb</a>
(6)
</li>
<li>
<strong>M</strong>
<a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319/files#diff-ef464a99e1a54021faabde556fab78a493ad34d36bc5f823ea7b2d22581de520">test/helpers/user_roles_helper_test.rb</a>
(76)
</li>
</ul>
<h4>Patch Links:</h4>
<ul>
<li><a href='https://github.com/openstreetmap/openstreetmap-website/pull/4319.patch'>https://github.com/openstreetmap/openstreetmap-website/pull/4319.patch</a></li>
<li><a href='https://github.com/openstreetmap/openstreetmap-website/pull/4319.diff'>https://github.com/openstreetmap/openstreetmap-website/pull/4319.diff</a></li>
</ul>
<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />Reply to this email directly, <a href="https://github.com/openstreetmap/openstreetmap-website/pull/4319">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AAK2OLMXDC5QKQJI6L74GMDYB2PDBAVCNFSM6AAAAAA6VBWHDWVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE3DOMJSG43TGMI">unsubscribe</a>.<br />You are receiving this because you are subscribed to this thread.<img src="https://github.com/notifications/beacon/AAK2OLNXJG6JGUDD5HXXCH3YB2PDBA5CNFSM6AAAAAA6VBWHDWWGG33NNVSW45C7OR4XAZNFJFZXG5LFVJRW63LNMVXHIX3JMTHHKP74WM.gif" height="1" width="1" alt="" /><span style="color: transparent; font-size: 0; display: none; visibility: hidden; overflow: hidden; opacity: 0; width: 0; height: 0; max-width: 0; max-height: 0; mso-hide: all">Message ID: <span><openstreetmap/openstreetmap-website/pull/4319</span><span>@</span><span>github</span><span>.</span><span>com></span></span></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/openstreetmap/openstreetmap-website/pull/4319",
"url": "https://github.com/openstreetmap/openstreetmap-website/pull/4319",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>