I think the model of having all events form a giant graph is overengineered. They tried to cope with this by introducing things like "fast room joins", but I think they are flawed and treat the symptom rather than the cause of the problem. Servers should only replicate the very core part of a room and fetch remaining information on demand. But I'm working together with the Matrix team to improve this in the future.
I think most other things in the spec are necessary complexity. It's annoying to work on logic for threads, spaces, read receipts, read receipts in threads and so on, but they allow Matrix to have a lot of great features.
What problems did you encounter writing bots for Matrix?