How can I purge a specific URL from varnish cache without making a curl request?
Here's some code that I use to clear Acquia varish via the Purge / Acquia purge modules when a pdf with the same name is uploaded.  You could expand on this to clear the styles cache as well.

/**
 * Implements hook_entity_update().
 */
function my_module_entity_update(EntityInterface $entity) {
  $type = $entity-&gt;getEntityTypeId();
  if ($type != 'file') {
    return;
  }
  // \Drupal::logger('my_module')-&gt;debug("File entity found");
  $purgeInvalidationFactory = \Drupal::service('purge.invalidation.factory');
  $purgeQueuers = \Drupal::service('purge.queuers');
  $purgeQueue = \Drupal::service('purge.queue');

  $queuer = $purgeQueuers-&gt;get('coretags');
  // Invalidate cache tags so all pages that have the file get banned from varnish
  // Also invalidate the file's url.
  $invalidations = [
      $purgeInvalidationFactory-&gt;get('tag', 'file:' . $entity-&gt;id()),
      $purgeInvalidationFactory-&gt;get('url', file_create_url($entity-&gt;getFileUri())),
  ];

  $purgeQueue-&gt;add($queuer, $invalidations);
}