One of the attributes on the IPluginExecutionContext is a depth. This indicates how 'deep' in the plugin 'call-stack' your plugin is executing. When you press save on the CRM Form you start at a depth of 1. Each time your post update calls update, the depth is increased.
You'll find some people will just check that the depth is equal to 1 before executing their plugin logic. This isn't right for everybody, however. If a workflow were to update this entity, then the depth would be 2 (workflow was 1, now your update is 2).
When the depth hits 8, CRM stops the execution calling it recursive. I'm not sure if you're actually hitting a timeout or this error. Its been a long time since I've seen what error they throw.
We've developed custom code throughout our solution where we have to check for recursion. I'm not in a position to share all of this, but you can have the idea if you like it.
Another couple of ideas is to add a custom attribute to your entity. Don't put it on the form. Normally that attribute wouldn't exist in your update property bag. When you call update from code that should short-circuit your update plugin next time, set the attribute. If the attribute is set, you would short circuit and not process the plugin.
Hope this helps.