* You have 18 services all using one database? Be aware that this pattern has the drawback that all of them are tightly coupled through the centralised database, and you might have a distributed monolith at hand. A typical symptom is that you have to release all services in lockstep. Consider your resources and and see if actually having a monolith, or at least consolidating some services, possibly could lead to a better development experience.
* Use semantic versioning inside the services. Version additive changes to the schema (adding a column) by bumping the minor version and flag old code paths "deprecated". Only remove columns that no other service is using once the code paths have been migrated from using the deprecated code paths, or use Feature Flags, like someone else mentioned.
You should add as much testing as possible - ideally have a central project that manages the database structure, and test each change carefully. Within each app, explicitly test that the app supports the intended new schema before moving to it.
Use a schema diff tool to autogenerate migration scripts and check that they result in a perfectly matching schema - I wrote `migra` that works with postgres, but there are good equivalents for most databases.
You conceptually need code paths to handle the different DB states asynchronously.