I&#x27;ve used both extensively. The practical differences between a goroutine and an Erlang process are small. The most significant difference is enforcement of isolation vs. isolation-by-convention (and bear in mind the latter is <i>not</i> the same as &quot;no isolation&quot;), but this is a bigger difference in theory than in fact.<p>OTP being missing matters less than you might initially think, too. I implement what bits of supervisor trees can be implemented here: <a href="https:&#x2F;&#x2F;github.com&#x2F;thejerf&#x2F;suture" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;thejerf&#x2F;suture</a> , and in general, with the way Go is structured, gen_servers and such just sort of melt away into &quot;things you interact with over channels&quot; without much fuss. (IMHO, OTP is generally a good thing, but the reification of gen_X so deeply into the language was an error. I actually prefer Go+Suture&#x27;s way of bringing up a server; much simpler, virtually no loss of capability in practice. Again, the theoretical difference turns out to be larger than the practical difference.)<p>(And before someone angrily smashes the reply button, pleases meditate on the distinction between a &quot;small difference&quot; and &quot;no difference&quot;, especially the subjective nature of such judgment calls. You can certainly quibble with the size I assign to the differences but please don&#x27;t reply as if I claimed <i>no</i> difference, or as if I have not demonstrated awareness of the difference between a strictly-enforced no-sharing environment vs. unenforced no-sharing convention, and, likewise, let&#x27;s not pretend &quot;isolation by convention&quot; is the same thing in practice as &quot;traditional shared-memory threading&quot;. Memory sharing <i>can</i> bite you in Go, and while I&#x27;ve gotten pretty used to the necessary patterns to avoid that (spending years in Erlang first is <i>really</i> good training for that), I don&#x27;t deny it is non-zero cognitive effort required.)