Skip to content


Choose a tag to compare
@Gargron Gargron released this 02 Sep 22:14




Federation relays (#7998)

A federation relay is a semi-centralized server that pushes public messages between Mastodon servers that want to use it, thereby increasing the exposure of all participating Mastodon servers to each other. This is a solution to the problem of new Mastodon servers not having any content at the beginning, a way to subscribe to a more or less global timeline.

Warning: Enabling a relay will mean faster database growth.

The relay server is open-source and anyone can operate one. Nothing is enabled by default, administrators can choose to join a relay and choose which relay to join. A default relay server is suggested when adding one.


Redesign public profiles and toots (#8068)

A more modern look ensures more consistency between the web UI and the public pages and is more suited to long profile bios. It also features the header image prominently.

Remote interaction dialog for toots (#8202)

You can click reply, boost or favourite on any public Mastodon page, and it will bring up a dialog similar to the "remote follow", where you need to enter your full username, upon which you will be redirected to your home instance with that toot opened and ready to be interacted with.

Display replies count in web UI (#8104, #8181)

You can now see when a toot has no replies, one reply, or many replies. Exact numbers are hidden to reduce popularity contests, but the feature is useful for knowing when someone still needs an answer, and when something has already been resolved.

Public profile endorsements (#8146)

You can now run a permanent follow friday on your public profile page. Anyone you follow, you can feature on your profile as a recommendation. Out of all the people you selected, 4 are displayed in random order. A good way to help others find cool accounts, or to link to your alts.


  • Display Mastodon version in footer of web UI (#8013)
  • Display full acct on public status pages, always (#8011)
  • Use LoadingBar instead of blur to indicate that an image is loading (fixes #4060) (#7562)
  • Show exact number of followers/statuses on export page/in tooltip (#8199)
  • Allow accessing local private/DM messages by URL (#8196)
  • Add "sign in to participate" message to public toot page (#8200)
  • Link to mobile apps page (#8278)
  • Make unfollow button light up red when hovered (#8286)
  • Specify allowed media in upload button tooltip. (#8443)
  • Add messages informing that collections are empty (fixes #4115) (#8418)


Resize images by area instead of fixed dimensions (#8083)

Previously the widest or tallest that a picture could be on Mastodon was 1280px, which was disastrous for things like comics that were much taller than they were wide. With the new technique, anything an image does not use up for its width it can use for its height, and vica versa.

Improved support for iOS videos (#8101)

MOV and WEBM videos will now be converted to MP4 for maximum compatibility, and there is now a special upload limit of 40mb for videos. Pictures are limited to 8mb as before.

Note: If you have a client_max_body_size directive in nginx, you will need to update it to 40m or higher instead of the previously recommended 8m.

Moderation UI:

Add confirmation step to account suspensions (#8353)

It will now be harder to make a mistake where you ban the wrong person. The new suspension screen asks you to type the username of the account you want to suspend for confirmation, and displays a summary of how many toots and followers will be deleted.

Allow mods to disable login and improve message when login disabled (#8329)

The function to lock someone out of their account temporarily will now be accessible to moderators as a preferable alternative to suspensions. Whereas previously a disabled login resulted in the login form erroring with the exact same message as when you hadn't confirmed your e-mail address, now it lets you login if your credentials are valid but displays a dead-end message.


  • Added preference to disable e-mail notifications for new reports (#8559)
  • If an unresolved report for the same account already exists, no new e-mails will be sent (#8559)

Admin UI:

Add admin dashboard (#8029)

Admins and mods can now view a summary of what's happening on their Mastodon server this week. Total user number, new sign ups, active users, number of interactions occuring, number of open reports, and other helpful snippets of information.

The interaction statistic is simply a weekly counter that is increased any time a local user replies, favourites, reblogs or follows someone.


  • Add separate setting for sidebar text (#8107)
  • Add admin function to deactivate all invites (#8279)
  • Add ability to change an default theme from admin UI (#8381)
  • Add custom CSS setting (#8399)


Support read-replicas (#8216)

You can now use a PostgreSQL hot streaming replica to spread the load on the database. See the new documentation on how to configure it.


  • Support UNIX domain socket for streaming service without using PORT (#8217)
  • Add health endpoint to streaming API (#8441)

Command-line interface:

This release comes with a new command-line interface for Mastodon: bin/tootctl

  • Add improved CLI interface for removing remote media (#8411)
  • Add CLI task for rotating keys (#8466)
  • Add CLI interface for importing custom emoji (#8437)

You can get more information from bin/tootctl --help


  • Add LDAP search filter option (#8151)


  • Move often-updated columns from statuses table to statuses_stats to decrease database I/O and disk usage growth (#8104)
  • Add missing indices for ON DELETE CASCADE constraints, thereby fixing slow account deletions, especially in the daily Scheduler::UserCleanupScheduler (#8332)


  • Give focused status a sensible aria-label for screen readers (#8387)
  • Add aria-label to notifications (#8460)
  • Add aria-label to column regions (#8390)
  • Fix off-by-one error in aria-posinset (#8388)
  • Add aria-label to floatingActionButton (#8574)

REST API additions:

  • replies_count on the Status entity
  • endorsed on the Relationship entity
  • GET /api/v1/endorsements to get endorsed accounts
  • POST /api/v1/accounts/:id/pin to endorse
  • POST /api/v1/accounts/:id/unpin to undo endorse


  • Add favourites to archive takeout (#8351)
  • Welsh, Tamil, Romanian languages added
  • Add animate custom emoji param to embed pages (#8507)
  • Self-notify on accepting follow requests (#8541)



The security patches described here have already been backported to v2.4.4.


  • Fix whole-word selection (#8004)
  • Do not cause an error if is undefined (#8021)
  • Hide "A look inside" in mobile layout on frontpage (#8044)
  • Ensure container of React components has full width (#8043)
  • Fix .column-back-button line-height (#8074)
  • Improve keyboard shortcuts descriptions (#8066)
  • Improve account bar css (#8087)
  • Order invites by recent first (#8091)
  • Do not scroll up when modal is opened (#8095)
  • Prevent scrolling main frame when navigating in image gallery with arrow keys (#8073)
  • Compensate for scrollbar disappearing when media modal visible (#8100)
  • Do not show pinned toots when min_id is set (#8111)
  • Render custom emoji in display name on public profile (#8115)
  • Scroll to linked status in public status view (fixes #7884) (#8130)
  • Remove protocol handler registration (#8127)
  • Fix crash when clicking “Show more/less for all” when a toot is not visible (#8118)
  • Various fixes regarding the video position slider (#8201)
  • Get rid of the Content Warning rainbows (#8129)
  • Defer scrollIntoView after DOM is drawn (fixes #8239) (#8242)
  • Fix #8264 - Do not override ctrl/cmd+click. (#8265)
  • Fix ctrl+enter not submitting toot when text cursor is composing image description (#8273)
  • Show compose form on delete & redraft when in mobile layout (#8277)
  • Make dropdown animations respect their placement (#8292)
  • Don't filter own toots (fixes #8289) (#8298)
  • Add hotkey for follow requests (#8307)
  • Skip pagination logic entirely for pinned toots (fixes #8302) (#8310)
  • reorder simple form ul to list vertically (fixes #8236) (#8322)
  • Allow use of plurals on about page stats. (#8363)
  • Update state when opened dropdown is unmounted (fixes #8397) (#8398)
  • Preserve hashtag casing in web UI hashtag history (#8394)
  • Only display web push notifications after API call (fixes #7902) (#8396)
  • Reword the "Delete and rewrite" warning (#8415)
  • Add missing video descriptions (#8416)
  • Hide reject media checkbox when not relevant. (#8426)
  • Wait until relationship is loaded before showing follow button (#8440)
  • Add theme identifier to body classes for easier custom CSS styling (#8439)
  • Add more hotkeys to legend (#8469)
  • Better singulars of account followers/toots. (#8471)
  • Fix wrong string being used on login failure when using LDAP (#8534)


  • Fix ActivityPub::UpdateDistributionWorker regression (#8039)
  • Fix incorrect context definition for the "featured" keyword (#8090)
  • Enforce username format for remote users, too (#8102)
  • Serialize text-less statuses as '.' over OStatus (fixes #7856) (#8126)
  • Use correct activity id in Accept when receiving duplicate Follow (fixes #8218) (#8244)
  • Implement Undo { Accept { Follow } } (fixes #8234) (#8245)
  • Do not process outgoing mentions to suspended accounts (#8272)
  • Support ActivityStreams’ summaryMap. (#8422)
  • Increase reach of Delete->Actor activities (#8305)
  • Do not sign useless User-Agent or Accept-Encoding headers (#8533)


  • Allow customizing user active duration (Default: 7 days) (#8282)
  • Keep scheduler jobs unique until they're done (#8287)
  • Do not check for file existence when serializing ActivityPub actor (#8386)
  • Disable retries on all scheduled tasks (#8413)


  • Dockerfile: run asset precompilation as a build step (#7780)
  • Remove annoying Notification#cache_ids scope warning (#8333)
  • Get rid of all batch order warnings (#8334)
  • Revert to using Paperclip's filesystem storage (#8339)
  • Get rid of Chewy order/limit warning (#8355)
  • Rename S3_CLOUDFRONT_HOST to S3_ALIAS_HOST. (#8423)
  • Fix pam authentication for certain hostnames (#8412)


  • Do not count self in potential friendships (#8014)
  • Fix static GIFs being saved as empty files when using local storage (#8012)
  • Fix streaming API still using filtered instead of chosen languages (#8009)
  • Disable language detection for texts shorter than 140 characters (#8010)
  • Whitelist dat/ipfs/gopher links in sanitizer (#8034)
  • Add secure option to additional cookie (#8069)
  • Call address instead of exchange (#8076)
  • Ensure single user is a local user (fixes #8154) (#8157)
  • Do not error out when performing admin actions on no statuses (#8220)
  • Do not only show silenced accounts to silenced accounts (#7528)
  • Avoid deleted attributes when building a Status from action log (fixes #8371) (#8373)
  • Do not crash if remote custom emoji does not define updated date (fixes #8376) (#8377)
  • Spread out crawling randomly to avoid DDoSing the link (#8445)
  • Delay e-mail notifications by 2 minutes (#8438)
  • Make Api::V1::MutesController paginate properly (#8472)

Upgrade notes:

As always, make sure you have backups of the database before performing any upgrades. If you are using docker-compose, this is how a backup command might look: docker exec mastodon_db_1 pg_dump -Fc -U postgres postgres > name_of_the_backup.dump

This is going to be a big one, so strap yourself in. The migration plan should involve zero downtime, but it will probably take a long time, possibly hours, to complete. Do not attempt it without a backup.

Non-Docker only:

  • Node.js 6.x is no longer supported, so you will need to upgrade to Node.js 8.x
    • curl -sL | sudo -E bash -
    • sudo apt update && sudo apt install nodejs
  • Install dependencies: bundle install and yarn install

Docker only:

If you had nginx/apache configuration expecting CSS/JS assets to be under volume folders, they are no longer there. Asset precompilation now happens during image build, and is therefore not available from a volume. Instead, requests for the assets must hit Puma inside Docker, which will serve them.

Both Docker and non-Docker:

  1. Run the pre-deployment database migrations by specifying the SKIP_POST_DEPLOYMENT_MIGRATIONS=true environment variable:
    • Non-Docker: SKIP_POST_DEPLOYMENT_MIGRATIONS=true RAILS_ENV=production bundle exec rails db:migrate
    • Docker: docker-compose run --rm -e SKIP_POST_DEPLOYMENT_MIGRATIONS=true web rails db:migrate
  2. Precompile the assets:
    • Non-Docker: RAILS_ENV=production bundle exec rails assets:precompile
    • Docker: The assets are already precompiled during the build step
  3. Restart all Mastodon processes
  4. Now that the new code is running, we can finish the database migrations. This will run the post-deployment ones:
    • Non-Docker: RAILS_ENV=production bundle exec rails db:migrate
    • Docker: docker-compose run --rm web rails db:migrate

Why? These migrations are cumbersome but are intended to improve performance and slow down database growth long-term. 🙏


Make sure to update client_max_body_size to 40m or higher.

Contributors to this release: