Storing posts from query and accessing later via AJAX call

Page load is a request, the software run, gives a response and close execution. Later Ajax is another request, totally separated. I you want objects to be persistently avaible between requests, you only have two options: use transients API or use object cache API combined with a cache plugin (object cache api is not persistent by default).

A very basic example of transients API:

if( false === ( $my_object = get_transient('transient_object_name') ) ) {

    // Build your $my_object here
    // For example
    $args= array();
    $query = new WP_Query( $args );

    $my_object = $query->get_results();

    // Store $my_object in a transient
    set_transient('transient_object_name', $my_object );
 }

Then, later, you can use get_transient('transient_object_name') to get the previously stored transient.

Transient API stores the object in the database (options table) to make possible to get it in subsequent requests without a new database call (well, one database call to get the transient but not the full operation to build the object).

Object Cache API is very similar but is not persistent by default. Its stores cached objects in memory instead of database and the object is cached only for current request. To make it persistent between separated requests, you need to use some persistent cache plugin, like W3TC.

If a persistent cache plugin is available, transient API stop storing the transient in database and works exactly like object cache API, storing in memory but data stored in memory is now persistent in both cases.