I have some experience designing and working on this style of architecture in a non-enterprise non-bigco environment. Some things I learned over the years:<p>1) If the system is young and the team is small, consider imposing constraints onto the system that remove certain classes of problems entirely. You can later lift these constraints as the team grows. [1]<p>2) Your ops environment must be capable of multiplexing multiple services onto the same virtual machine. The way you provision and classify machines is affected by this. Services, by their nature, are small and are likely going to be I/O bound. Deploying multiple services onto a single machine is very cost effective.<p>3) If you're starting with a monolith, the best early candidates to break off are things like search, graph stuff (eg: Neo4j), recommendations, activity feeds, image processing, and other important but non-critical things. It's a great way to drum up support for this architectural style and/or test how useful it will really be.<p>4) Unless your engineering team has a polyglot culture (good for you!), be careful about introducing your favorite language when building a new service. Alienating services is a great way for them to rot.<p>5) I've been asked how to define a service. Should X be one service? Should X be split into two services? A good way to start is to think about data locality. When a "user" is fetched are "friends" almost always queried too? If so, keep them together. The next thing to look at are traffic patterns. Another thought exercise is to ask, "if our startup makes a hard pivot tomorrow, what are we likely going to keep? Users?".<p>6) Do what makes sense. A small startup with a 5 person team doesn't need 20 "microservices" to maintain. It's an operational burden. Break things away in stages on an as needed basis. I've actually found that keeping around the monolith is a great outlet for rapidly prototyping. Give the monolith a beefy database and an in-memory datastore. When you need to prototype a feature for a week, feed it to the monolith. When it's ready for production, break it off if it makes sense.<p>7) If your ops environment is underdeveloped, it'll hurt bad. The value of a good ops person cannot be overstated (esp. if you're dealing with rapid growth). They're wizards. Learn everything you can from them.<p>[1]: I like to impose a constraint that no service is allowed to talk to any other service unless it is: a) customer facing (eg: the website or the mobile api), or b) non-critical and low volume. At first, your services will act as self contained front ends to their databases. Your customer facing applications will stitch together responses from these services (hopefully in parallel). You'll have a clear understanding of how data flows in your system.