This is because xDB data is not committed until after the user's session ends.
This link contains a little more information on why that is: https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/xdb/session_state/session_state
Session state is a way of identifying contacts on your website by assigning them a unique session ID and by using cookies. Every time a contact makes a request, such as triggering a campaign or a goal this information is held in session state until the end of session.
This means that fewer server trips are needed to write data back and forth to the collection database. Instead, xDB makes one trip at the start of a session to identify the contact and a second at the end to save all the session data back to the collection database.
The xDB data is committed in the postSessionEnd
pipeline if I'm not mistaken. There is also the sessionEnd
pipeline which handles some analytics stuff among other things and is run before the postSessionEnd
pipeline (obviously).
<sessionEnd>
<!-- ... -->
<processor type="Sitecore.Analytics.Pipelines.SessionEnd.InitializeTracker, Sitecore.Analytics" patch:source="Sitecore.Analytics.Tracking.config"/>
<processor type="Sitecore.Analytics.Pipelines.SessionEnd.RaiseVisitEnd,Sitecore.Analytics" patch:source="Sitecore.Analytics.config"/>
</sessionEnd>
<postSessionEnd>
<processor type="Sitecore.Analytics.Pipelines.PostSessionEnd.CommitSession, Sitecore.Analytics" patch:source="Sitecore.Analytics.Tracking.Database.config"/>
</postSessionEnd>
I don't know enough about engagement plans to offer any advice on wether or not it is suited for sending notifications immediately.